Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complex models and partial views - model binding issue in ASP.NET MVC 3

I have 2 models in my sample MVC 3 application, SimpleModel and ComplexModel, shown below:

public class SimpleModel
{
    public string Status { get; set; }
}

public class ComplexModel
{
    public ComplexModel()
    {
        Simple = new SimpleModel();
    }

    public SimpleModel Simple{ get; set; }
}

I have defined views for this models:

_SimplePartial.cshtml:

@model SimpleModel

@Html.LabelFor(model => model.Status)
@Html.EditorFor(model => model.Status)

and Complex.cshtml:

@model ComplexModel

@using (Html.BeginForm()) {

    @Html.Partial("_SimplePartial", Model.Simple)
    <input type="submit" value="Save" />
}

After submitting form, with random value entered in Status field, the value is not binded to my model. The Status field is NULL when I'm checking the model in my controller action:

[HttpPost]
public ActionResult Complex(ComplexModel model)
{
    // model.Simple.Status is NULL, why ?
}

Why is it not binded ? I don't want to inherit models. Do I have to write my custom model binders for such simple case ?

Regards.

like image 955
jwaliszko Avatar asked Mar 04 '11 17:03

jwaliszko


People also ask

How do you bind a model with partial view?

To create a partial view, right click on Shared folder -> select Add -> click on View.. Note: If the partial view will be shared with multiple views, then create it in the Shared folder; otherwise you can create the partial view in the same folder where it is going to be used.

What is model binding in ASP.NET MVC?

What Is Model Binding? ASP.NET MVC model binding allows mapping HTTP request data with a model. It is the procedure of creating . NET objects using the data sent by the browser in an HTTP request. Model binding is a well-designed bridge between the HTTP request and the C# action methods.

What is difference between view and partial view in MVC?

View can basically contains a complete markup which may contain a master view(or master page) with all the design(s) etc. whereas Partial view is only a portion of page or a small markup which don't have master page. It is basically used as user control in mvc and it can be used at more than one views.


2 Answers

Instead of:

@Html.Partial("_SimplePartial", Model.Simple) 

I would recommend you using Editor templates:

@model ComplexModel @using (Html.BeginForm())  {     @Html.EditorFor(x => x.Simple)     <input type="submit" value="Save" /> } 

and then put the simple partial inside ~/Views/Shared/EditorTemplates/SimpleModel.cshtml or inside ~/Views/Home/EditorTemplates/SimpleModel.cshtml where Home is the name of your controller:

@model SimpleModel @Html.LabelFor(model => model.Status) @Html.EditorFor(model => model.Status) 

Of course if you prefer to have the partial in some special location and not follow the conventions (why would you?) you could specify the location:

@Html.EditorFor(x => x.Simple, "~/Views/SomeUnexpectedLocation/_SimplePartial.cshtml") 

then everything will come into place as expected.

like image 151
Darin Dimitrov Avatar answered Oct 11 '22 06:10

Darin Dimitrov


As Daniel Hall suggests in his blog, pass a ViewDataDictionary with a TemplateInfo where HtmlFieldPrefix is set to the name of the SimpleModel-property:

 @Html.Partial("_SimplePartial", Model.Simple, new ViewDataDictionary(ViewData)
    {
        TemplateInfo = new System.Web.Mvc.TemplateInfo
        {
            HtmlFieldPrefix = "Simple"
        }
    })
like image 24
toralux Avatar answered Oct 11 '22 08:10

toralux