你如何在mvc 2中创建包含列表的表单?

时间:2011-02-22 18:51:36

标签: c# asp.net-mvc asp.net-mvc-2 c#-4.0

我有一个包含两个对象的模型,一个是带有验证和属性的类来描述新的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; }
}

我的控制器看起来像这样,它只是创建一个新实例,并创建列表条目和一些默认的员工属性值。

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

视图如下所示:

<% 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" />

&lt;%}%&gt;

表单呈现正常,我看到员工数据的部分视图,以及访问列表的12个部分视图。

不幸的是,当点击创建按钮并且页面发布时,模型将返回null属性。

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

如果查看Request.Form,它看起来像这样:

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=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=&Comments=

显然这不是这样做的方法。我的问题是,创建这样的表单的正确方法是什么?

我的尝试是否有瑕疵,应该报废并重新开始?

2 个答案:

答案 0 :(得分:2)

尝试使用编辑器模板:

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

~/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>
...

现在应该正确绑定到:

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

因为将为集合的每个元素呈现编辑器模板,您可能希望向此集合添加一些项目,您将传递GET操作(EmployeeViewModel.NewEmployee)。

答案 1 :(得分:0)

我认为你遇到的问题是,在一种形式中,你有多次渲染相同的字段。在html中,您可以执行此操作,但只有在使用正确的符号区分字段时才会这样:

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

然后,大多数服务器端语言允许您通过索引引用发布数据中的正确“请求”,如:posdata [requested] [0](伪代码)。如果您的html输出看起来与此类似,那么您将不得不想出另一种渲染表单的方法。一旦你这样做,问题是,默认的ModelBinder是否可以处理它并正确返回该属性的列表