开发者

How do you do a Create form in mvc 2 that contains lists?

I have a model with two objects, one is a class with validations and properties to describe a new Employee, the second is a list of possible access's that may need to be granted to the new employee.

public class EmployeeViewModel
{
    public NewEmployee.Models.EmployeeModel Employee { get; set; }
    public IList<RequestedAccessViewModel> AvailibleAccesses { get; set; }
}
public partial class EmployeeModel
{
    public DateTime DateRequested { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Initials { get; set; }
    public string UserName { get; set; }
    public string Department { get; set; }
    public string RequestedLocation { get; set; }
    public string CubicleNumber { get; set; }
    public string Supervisor { get; set; }
    public DateTime StartDate { get; set; }
    public string EmployeeJobFunction { get; set; }
    public int Id { get; set; }
}
public class RequestedAccessViewModel
{
    public string Description { get; set; }
    public bool Requested { get; set; }
    public string Comments { get; set; }
    public int Id { get; set; }
}

My Controller looks like this, which just creates a new instance, and creates the list entries, and some default employee property values.

[HttpGet]
public ActionResult Create()
{
    return View(EmployeeViewModel.NewEmployee());
}

The view looks like this:

<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<% Html.RenderPartial("CreateEmployeeData", Model.Employee); %>
<%
    foreach (var access in Model.AvailibleAccesses)
    {
        Html.RenderPartial("CreateRequestedAccessViewModel", access);
    }
%>
<input type="submit" value="Create" />

<% } %>

The form renders ok, I see the partial view for the employee data, and the 12 partial views for the access list.

Unfortunaly, when the create button is hit and the page posts, the model comes back with null properties.

[HttpPost]
public ActionResult Create(EmployeeViewModel model)
{
    // "model" is not null, but it's two properties are!
}

If you look at Request.Form, it looks like this:

DateRequested=2%2f22%2f2011+12%3a47%3a22+PM&
FirstName=&
LastName=&
Initials=&
UserName=&
Department=&
RequestedLocation=&
CubicleNumber=&
Supervisor=asawyer&
StartDate=2%2f25%2f2011+12%3a47%3a22+PM&
EmployeeJobFunction=&
Id=0&Id=0&Id=0&Id=0&Id=0&Id=0&Id=0&Id=0&Id=0&Id=0&Id=0&Id=0&Id=0&Id=0&
Requested=false&Requested=false&Requested=false&Requested=false&Requested=false&Requested=false&Requested=false&Requested=false&Requested=false&Requested=false&Requested=false&Requested=false&Requested=false&
Comments=&Comments=&开发者_StackOverflow中文版;Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=

It's pretty apparently this is not the way to do this. My question is then, what is the correct way to create a form like this?

Is my attempt so flawed it should be scrapped and start over?


Try using an editor template:

<% using (Html.BeginForm()) {%>
    <%: Html.ValidationSummary(true) %>
    <% Html.RenderPartial("CreateEmployeeData", Model.Employee); %>
    <%: Html.EditorFor(x => x.AvailibleAccesses)
    <input type="submit" value="Create" />
<% } %>

and inside ~/Views/Shared/EditorTemplates/RequestedAccessViewModel.ascx:

<%@ Control 
    Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.RequestedAccessViewModel>" 
%>
<div>
    <%: Html.LabelFor(x => x.Description) %>
    <%: Html.TextBoxFor(x => x.Description) %>
</div>
...

Now this should be correctly bound to:

[HttpPost]
public ActionResult Create(EmployeeViewModel employee)
{
    ...
}

Because the editor template will be rendered for each element of the collection you might want to add some items to this collection you are passing in the GET action (EmployeeViewModel.NewEmployee).


I think the problem you are having is that in one form, you have the same fields rendered multiple times. In html, you are allowed to do this, but ONLY if you differentiate the fields using the correct notation like this:

<form>
  <input type="text" name="requested[]" />
  <input type="text" name="requested[]" />
  ...
</form>

Then, most server side languages allow you to reference the correct 'requested' in the post data by index like: posdata[requested][0] (pseudocode). If you html output doesn't look similar to this, then you will have to come up with another way to render your form. Once you do that, the question is, whether or not the default ModelBinder can handle it and return a list of that property correctly

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜