Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorrect model property value rendered in partial view

I have a strongly-typed partial view whose model contains a property with the same name as the parent page's view model. For some reason the rendering engine is rendering the parent view model value, not the expected value (well, the value I expect at least!)

Parent page view model extract:

public class ParentPageViewModel
{
    public int Id { get; set; } // problem property
    ...
    public IEnumerable<ChildViewModel> Children { get; set; }
}

Child page view model extract:

public class ChildViewModel
{
    public int Id { get; set; } // problem property
    ...
}

Parent page extract (Razor):

@model ParentPageViewModel
...
@foreach (var item in Model.Children)
{
    @Html.Partial("MyPartialView", item)
}
...

Partial view extract:

@model ChildViewModel
...
<form ...>
    @Html.HiddenFor(m => m.Id) // problem here - get ParentPageViewModel.ID not ChildViewModel.Id
</form>
...

So basically in my rendered output, my hidden field has the value of the parent view model element, NOT the value passed to the partial view. It's definitely being caused by the name, as changing the name of @ChildViewModel.Id@ to something like @ChildViewModel.ChildId@ makes it work as expected. Interestingly, when inspecting the view model values in the debugger I do see the correct values; it's only the rendered output that's wrong.

Is there a way round this or 'correct' way of doing what I'm trying to do (I'm rendering mini forms in a table for ajax validation/posting of updates to table rows)

Thanks,

Tim

like image 381
Tim Croydon Avatar asked Aug 07 '12 10:08

Tim Croydon


People also ask

Can we use model in partial view?

Partial Views can use the Page Model for their data whereas Child Actions use independent data from the Controller. Editor/Display templates pass items from the model to the system but can be overridden by user partial views.

How do you pass model data to 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.

How does a partial view support a model?

It helps us to reduce code duplication. In other word a partial view enables us to render a view within the parent view. The partial view is instantiated with its own copy of a ViewDataDictionary object which is available with the parent view so that partial view can access the data of the parent view.

Can we return partial view from action method?

To return a Partial view from the controller action method, we can write return type as PartialViewResult and return using PartialView method.


2 Answers

Found a solution, just manually creating the hidden field, e.g.:

<input type="hidden" name="Id" value="@Model.Id" />

instead of using Html.HiddenFor.

(I won't mark this as answered for a while in case there are any other solutions or anyone can explain the problem)

like image 36
Tim Croydon Avatar answered Oct 20 '22 04:10

Tim Croydon


I think changing your call to this will solve the problem:

@Html.Partial("MyPartialView", item, new ViewDataDictionary())

The child view is picking up the value from the ViewData dictionary - so this passes in a new dictionary to the child view (hattip danludwig).

like image 104
Simon Avatar answered Oct 20 '22 04:10

Simon