Slavisa
Slavisa

Reputation: 966

How to pass complex data as model from view to controller in mvc 2

I have following in database (and I use them as models):

Category
{
long id;
string name;
long subcategoryId;
}

Subcategory
{
long id;
string subName;
//other data
}

I get data from db with Entity SQL like:

public static Category GetCategory(long catId)
        {
            Category cat;
            using (Entities db = new Entities())
            {
                cat = (from c in db.Categories
                       where c.id == catId
                       select c).SingleOrDefault();

                cat.SubcategoryReference.Load();
            }
            return cat;
        }

Now, I have some partial view:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Test.Database.Subcategory>>" %>
<%--Some code--%>
<%:Html.ActionLink("Move to new category", "editcategory", "category",
                                             new { model = new Category { Subcategory = item } }, null)%>

Plan is to navigate with this action link to CategoryController and action

public ActionResult EditCategory(Category model)
        {
            //some code
            return View(model);
        }

where I can edit some info about this category which would contain chosen subcategory. Problem is that I keep getting model=null as parameter in this EditCategory Action. What am I doing wrong? Any advice is welcome.

Upvotes: 2

Views: 2129

Answers (2)

hunter
hunter

Reputation: 63522

You might want to reconsider how you're passing this object to your action link and load the data from within the controller

public ActionResult EditCategory(long id)
{
    Category model = id > 0 
        ? GetCategory(long id)
        : new Category() { Subcategory = item };

    return View(model);
}

[HttpPost]
public ActionResult EditCategory(int id, Category category)
{
    if (ModelState.IsValid) { /* save then redirect */ }
    return View();

}

and construct your action links like this:

<%:Html.ActionLink("Move to new category", 
    "editcategory", "category", new { id = 0 }, null)%>

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038930

You cannot pass complex objects using GET as action links. If you wanted to do this you will need to send all properties, one by one and leave the default model binder cope with it but this could be very tedious:

<%: Html.ActionLink(
    "Move to new category", 
    "editcategory", 
    "category",
    new { 
        prop1 = item.Prop1,
        prop2 = item.Prop2,
        ...
    }, 
    null
)%>

I would recommend you the standard way to achieve which consists in passing the category id that you are willing to edit:

<%: Html.ActionLink(
    "Move to new category", 
    "editcategory", 
    "category",
    new { id = item.Id }, 
    null
) %>

and inside the controller action fetch the corresponding model from the repository:

public ActionResult EditCategory(int id)
{
    Category model = ... fetch category from id
    //some code
    return View(model);
}

Then the corresponding view will contain a form with input fields for all the different category properties and it is the POST action which you will submit this form to that can take a Category model as action parameter:

[HttpPost]
public ActionResult EditCategory(Category category)
{
    if (!ModelState.IsValid) 
    {
        return View(model);
    }
    // some code to update the category
    return RedirectToAction("Success");
}

Upvotes: 2

Related Questions