简体   繁体   中英

MVC 4 Razor, Posting form with partial views

I am new to MVC 4 and razor. I have a view which contains multiple partial views. Due to the functionality of the partial views I am planning to reuse these in other views also.

My model is a collection of complex objects eg:

    public class EmployeeInfo
    {
        public EmployeeContactInfo contactInfo { get; set; }
        public List<TelephoneInfo> phoneDetails { get; set; }
        public AddressDetails addressDetails { get; set; }
    }

The model of my main view is EmployeeInfo and other partial views have models as TelephoneInfo , EmployeeContactInfo and AddressDetails respectively.

I tried using RenderPartial , RenderAction and Partial to load my partial views eg:

    @using (Html.BeginForm())
    {
    @Html.Partial("ContactInfo",Model.contactInfo)
    }

When the main form is submitted the main model doesnt have the updated values of the partial views.

I searched for this and found below 2 proposed solutions:

  1. Use EditorFor - It works and the model gets updated but I have collection of not only textbox but other controls which have some internal operations (like searching addresses) too and I also need to reuse the same partial view in other places (like a user control in classic ASP.NET)

  2. Use RenderAction instead of RenderPartial - It didn't work for me.

Please let me know if I am going wrong or understood anything incorrectly.

Another choice is to create an editor template . For example, in your main view:

@using (Html.BeginForm())
{
    @(Html.EditorFor(m => m.ContactInfo))
}

Now, in your Views/Shared folder (or the Views/ControllerName folder eg Views/Home), create a new folder named "EditorTemplates". In that new folder create a cshtml view file named EmployeeContactInfo.cshtml (tip, the name of the cshtml should be the data type name eg string , bool or in this case your customer contact info type). In that view file, put something like:

@model EmployeeContactInfo

@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)

When you post back to the controller, the values will be included as part of the returned model for you.

The problem is that your main form is expecting elements with the name contactInfo.property, probably in you partial the names you generate are property without the right identifiers, this issue create problems with the default model binder of MVC. You can create a custom model binder, but with hard work, or you have two ways to solve your issue with less work.

1. Force the name of the generated element

For example, if your EmployeeContactInfo class contains a string Address property you have to use this helper:

@Html.TextBox("contactInfo.Address", model.Address)

that results in:

<input type="text" name="contactInfo.Address" id="contactInfo_Address" />

instead of:

@Html.TextBoxFor(m=> m.Address)

that results in:

<input type="text" name="Address" id="Address" />

2. Pass the entire model:

If you pass the entire model the generated name would be correct, so you can use the helper:

@Html.TextBoxFor(m=> m.contactInfo.Address)

that results in:

<input type="text" name="contactInfo.Address" id="contactInfo_Address" />

Partial View page acts like User Control

  1. Here _login.cshtml is partial view
  2. If you use partial view then underscore followed by name:

    <div style = "margin:3%;"> @Html.Partial("~/Views/Shared/_login.cshtml",Model.login)
    </div>

  3. Model.login is a object. So in this object you can assign value whatever page.

  4. Partial will show based on object value.

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