简体   繁体   中英

MVC3 - Pass back a model from RenderPartial

I have a page in MVC3 with a model of "pageModel".

In this page I have:

@{ Html.RenderPartial("_subPage", Model.subModel); } (Pagemodel.submodel)

In my controller I am doing:

 [Authorize]
 [AcceptVerbs(HttpVerbs.Post)]
 public ActionResult Results(pagemodel model, string frmAction)
 {
 }

The page loads fine the first time, but when I postback into the httpPost action, model.submodel is always null.

My question is, how do I return an updated model from the RenderPartial (if at all). I can get my model INTO the partial, but not back!

The problem with partials is that they do not preserve the navigational context. This means that any input fields that you might have put inside this partial will have incorrect names and the default model binder will not be able to retrieve the values back when you POST. Your HTML will look like this:

<input type="text" name="Prop1" value="property 1 value" />
<input type="text" name="Prop2" value="property 2 value" />

whereas the correct is:

<input type="text" name="subModel.Prop1" value="property 1 value" />
<input type="text" name="subModel.Prop2" value="property 2 value" />

In order to achieve this correct markup I would recommend you using editor templates.

So you replace:

@{ Html.RenderPartial("_subPage", Model.subModel); }

with:

@Html.EditorFor(x => x.subModel)

and then you move your _subPage.cshtml partial into ~/Views/Shared/EditorTemplates/SubModelType.cshtml where SubModelType is the type of the subModel property:

@model SubModelType
@Html.EditorFor(x => x.Prop1)
@Html.EditorFor(x => x.Prop2)

Now when you look at the generated HTML the corresponding input field names should be prefixed with subModel and inside the POST controller action the model.subModel property will this time be properly initialized and populated from the values that were entered by the user in the input fields.

You can also perform the following.

@Html.RenderPartial(
    "_subPage",
    Model.subModel,
    new ViewDataDictionary
    {
        TemplateInfo = new TemplateInfo
        {
            HtmlFieldPrefix = "subModel"
        }
    });

Your partial view will remain as is, using the @model SubModel

you'll need to change your partialview to accept the top level model, ie:

@{ Html.RenderPartial("_subPage", Model); } 

which would then render your properties in the partialview with the correct property names ie :

<input type="text" name="subModel.MyProperty" value="somevalue" />

It would also mean that your returned model in the HttpPost action will have to correct navigational relationship intact.

this is just one of those caveats related to viewmodels and hierarchies. Oh, btw, in mvc3, you don't need the verbose [AcceptVerbs(HttpVerbs.Post)] for posts. You can simply use [HttpPost]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM