Fabiano
Fabiano

Reputation: 5194

Bind model back when displayed with DisplayFor template

I have the model

public class PersonViewModel
{
    public Guid Id { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

which is nested in an other view model:

public class ApprovalModel
{
    [UIHint("MyDisplayTemplate")]
    public PersonViewModel User { get; set; }

    [Required]
    public bool? Approve { get; set; }
}

Under Views -> Shared -> DisplayTemplates I have the template MyDisplayTemplate.ascx

In my view ApprovalModel view I use the following line, which displays the nested model:

<div class="display-field"> <%: Html.DisplayFor(model => model.User) %> </div>

And in my controller I have the action

[HttpPost]
public virtual ActionResult ApproveRequest(ApprovalModel vm)
{
    //access bound vm.User  here
}

Is there a simple way to bind the nested model back with the post request? Or what else can I do to bind it back?

thanks

Upvotes: 0

Views: 2413

Answers (3)

Francesco Abbruzzese
Francesco Abbruzzese

Reputation: 4149

You don't need to put the fileds in textboxes you just need to put it in some input fields, so when the page is posted back those values are sent back to the server. Therefore simply use HiddenFor(....) for each field you want to recovery on post back

Upvotes: 1

Thomas Eyde
Thomas Eyde

Reputation: 3934

Save your view model in Session and render the id as a hidden field. Then your post action can retrieve the model from Session or load it by the id if it isn't there.

View:

<%: Html.HiddenFor(x => x.Id) %>

Controller:

[HttpPost]
public virtual ActionResult ApproveRequest(int id)
{
    //access bound vm.User  here
}

Upvotes: 2

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

You need input fields in the display template:

<%: Html.HiddenFor(x => x.Id) %>
<%: Html.LabelFor(x => x.Firstname) %>
<%: Html.TextBoxFor(x => x.Firstname) %>
<br/>
<%: Html.LabelFor(x => x.Lastname) %>
<%: Html.TextBoxFor(x => x.Lastname) %>

And in your controller action indicate the User prefix so that the model binder is capable of correctly recognizing the request values and binding them to ApprovalModel.

[HttpPost]
public ActionResult ApproveRequest([Bind(Prefix = "User")] ApprovalModel vm)

Also editor templates seems more appropriate (<%: Html.EditorFor(model => model.User) %>) for generating forms and input fields instead of display templates.

Upvotes: 2

Related Questions