View模型列表属性从post方法变为null

时间:2014-02-06 19:30:28

标签: c# asp.net asp.net-mvc asp.net-mvc-4

我有一个视图模型,里面有一个列表。当我通过邮件将数据发送到控制器时,列表将为空。

有什么问题?

查看:

@model MyProject.ViewModel.MyViewModel

@{
    var grid = new WebGrid(Model.MyList);
}

@using(Html.BeginForm())
{
    @grid.GetHtml(columns: grid.Columns(grid.Column(header: "Column", format: @<text><input name="Add" type="checkbox"  @(item.Checked == true ? "Checked" : null) />@item.Name</text>)))

    <button type="submit">Send</button>
}

控制器:

[HttpPost]
public ActionResult MyMethod(MyViewModel viewModel)
{
    // In this point, my list is comming null.
    return View();
}

视图模型:

public class ObjectModel
{
    public string Name { get; set; }
    public bool Checked { get; set; }
}

public class MyViewModel
{
    public MyViewModel()
    {
        this.MyList = new List<ObjectModel>();
    }

    public List<ObjectModel> MyList { get; set; }
}

1 个答案:

答案 0 :(得分:0)

您的问题是,在提交默认模型后,活页夹无法正确绑定您的数据。为了能够这样做,你的输入元素必须在其name属性中包含适当的语法,如:

<input name="MyList[0].Name"
<input name="MyList[1].Name"
//and so on

实际上有一些解决方案可以解决您的挑战。我个人会创建自己的自定义绑定器,然后遍历FormCollection。为了能够区分不同的项目,您必须更改此部分:

<input name="Add"

成:

<input name="Add" value="@item.Name"

然后您的自定义活页夹可能如下所示:

public class MyViewModelBinder: IModelBinder
{
    public object BindModel(ControllerContext controllerContext, 
                            ModelBindingContext bindingContext)
    {
        HttpRequestBase request = controllerContext.HttpContext.Request;

        List<ObjectModel> list = new List<ObjectModel>(); 
        var ids= form.GetValues("Add"); 
        //in your case your ids would be the names of your items
        foreach (var id in ids)
        {
           list.Add(new ObjectModel(){ Name = id, Checked= true});  
        }

        return new MyViewModel
                   {
                       MyList = list
                   };
    }
} 

最后,您应将此添加到全局模型绑定器集合中:

protected void Application_Start()
{
    // some configuration code
    ModelBinders.Binders.Add(typeof(MyViewModel), new MyViewModelBinder());
}

您可以将其设置为MyViewModel的默认模型绑定器,或者只是将其添加到MyMethod操作:

[HttpPost]
public ActionResult MyMethod
  ([ModelBinder(typeof(MyViewModelBinder))]MyViewModel viewModel)
{
    // In this point, your list will not come null
    return View();
}