45

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.

1
  • Is possible to do this, but maybe casting the Simple object to something so all the fields aren't editable? Commented Mar 1, 2012 at 15:21

2 Answers 2

62

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.

Sign up to request clarification or add additional context in comments.

8 Comments

Seems ok but there is one drawback. The id attribute of Status field has changed from 'Status' to 'Simple_Status'. Because of this my javascript stops working. Is there any way to tell MVC not to change the default id's of elements ? Since I'm not going to include multiple views using the same model, the id's will be always unique. Still, mabye more correct way is to just fix js ?
The answer is helpful. but @Html.EditorFor(x => x.Simple) will display all the properties of SimpleModel Class. But if I want to display only few properties, how could I achieve it?
ok, but if I want to add a new item to collection?? I need a javascript when I click the button to add new item. Which one is the best approach?
@LeandroDeMelloFagundes if you want a dynamic list on the client to edit. Then check Knockout or Angular. Those are client MVC frameworks. You can then post the whole object with dynamic list to the server.
It seems the path to "SomeUnexpectedLocation" of this questions ain't supported by EditorFor control.
|
26

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"
        }
    })

3 Comments

public static ViewDataDictionary<T> WithFieldPrefix<T>(this ViewDataDictionary<T> viewData, string fieldPrefix) { return new ViewDataDictionary<T>(viewData) { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = fieldPrefix } }; }
I like this answer. because most of the time I need to use Partial in complex models.
This is the one to use!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.