7

我正在尝试编写自定义模型绑定器,但我很难弄清楚如何绑定复杂的复合对象。

这是我要绑定的类:

public class Fund
{
        public int Id { get; set; }
        public string Name { get; set; }
        public List<FundAllocation> FundAllocations { get; set; }
}

这就是我尝试编写自定义活页夹的样子:

public class FundModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        throw new NotImplementedException();
    }

    public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState)
    {
        var fund = new Fund();

        fund.Id = int.Parse(controllerContext.HttpContext.Request.Form["Id"]);
        fund.Name = controllerContext.HttpContext.Request.Form["Name"];

        //i don't know how to bind to the list property :(
        fund.FundItems[0].Catalogue.Id = controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"];
        return fund;
    }
}

有任何想法吗

谢谢托尼

4

2 回答 2

8

你真的需要在这里实现一个自定义的 ModelBinder 吗?默认绑定器可以满足您的需要(因为它可以填充集合和复杂对象):

假设您的控制器操作如下所示:

public ActionResult SomeAction(Fund fund)
{
  //do some stuff
  return View();
}

你的 html 包含这个:

<input type="text" name="fund.Id" value="1" />
<input type="text" name="fund.Name" value="SomeName" />

<input type="text" name="fund.FundAllocations.Index" value="0" />
<input type="text" name="fund.FundAllocations[0].SomeProperty" value="abc" />

<input type="text" name="fund.FundAllocations.Index" value="1" />
<input type="text" name="fund.FundAllocations[1].SomeProperty" value="xyz" />

默认模型绑定器应使用 FundAllocations 列表中的 2 个项目初始化您的基金对象(我不知道您的 FundAllocation 类是什么样的,所以我组成了一个属性“SomeProperty”)。只需确保包含那些“fund.FundAllocations.Index”元素(默认活页夹查看它以供自己使用),当我试图让它工作时让我得到了)。

于 2009-04-22T10:43:18.157 回答
3

我最近在同样的事情上花了太多钱!

在没有看到您的 HTML 表单的情况下,我猜它只是从多选列表或其他内容中返回选择结果?如果是这样,您的表单只是返回一堆整数,而不是返回您的水合FundAllocations对象。如果您想这样做,那么在您的自定义 ModelBinder 中,您将需要自己进行查找并自己水合对象。

就像是:

fund.FundAllocations = 
      repository.Where(f => 
      controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"].Contains(f.Id.ToString()); 

当然,我的 LINQ 只是示例,您显然可以随心所欲地检索数据。顺便说一句,我知道它不能回答你的问题,但经过一番折腾后,我决定对于复杂的对象,我最好使用 ViewModel 并将默认的 ModelBinder 绑定到它,然后,如果我需要,水合物代表我的实体的模型。我遇到了许多问题,这些问题使它成为最佳选择,我现在不会让你厌烦它们,但如果你愿意,我很乐意推断。

最新的Herding Code 播客对此进行了很好的讨论,K Scott Allen 的 Putting the M in MVC 博客文章也是如此。

于 2009-04-22T10:18:23.910 回答