Asp.net mvc ASP.NET MVC:在将表单POST绑定到参数时避免紧密耦合

Asp.net mvc ASP.NET MVC:在将表单POST绑定到参数时避免紧密耦合,asp.net-mvc,modelbinders,defaultmodelbinder,Asp.net Mvc,Modelbinders,Defaultmodelbinder,假设我有一个界面,比如: interface IThing { int Id { get; set; } string Title { get; set; } } 在ASP.NET MVC中,我有一个表单,它向控制器发送如下操作: [AcceptVerbs(HttpVerbs.Post)] public ActionResult NewThing([Bind(Exclude = "Id")] SimpleThing thing) { // code to valida

假设我有一个界面,比如:

interface IThing {
   int Id { get; set; }
   string Title { get; set; }
}
在ASP.NET MVC中,我有一个表单,它向控制器发送如下操作:

 [AcceptVerbs(HttpVerbs.Post)]
 public ActionResult NewThing([Bind(Exclude = "Id")] SimpleThing thing) {

    // code to validate and persist the thing can go here            
 }
public class FactoryModelBinder<T> 
    : DefaultModelBinder 
    where T : new() 
{

    protected override object CreateModel(ControllerContext controllerContext, 
                                          ModelBindingContext bindingContext, 
                                          Type modelType) {

        return new T();                       
    }

}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NewThing([Bind(Exclude = "Id")] IThing thing) {
    // code to process the thing goes here
}
SimpleThing是一个仅仅实现了它的具体类

但是,我希望我的所有方法都能处理这个接口。我有一个数据程序集,它使用NHiberate及其自己的IThing实现(我们称之为RealThing)。我不能把简单的东西传给它,因为它会抱怨“未知实体”

有没有人想到一种更干净的方法?我在考虑使用factory类。但是我如何让MVC表单绑定器使用它呢


谢谢

您可以使用自定义。然而,关于msdn的文章是完全无用的。所以最好使用搜索,找到更好的东西。有很多文章可供参考。

我想出了两种方法

第一个是向我的NHibernate Repository类添加代码,以将MVC控制器使用的简单POCO类型(SimpleThing)转换为NHibernate需要的实体类型(RealThing):



我喜欢第二种方法,但我的大部分依赖注入内容都在控制器类中。我不想在Global.asax.cs中添加所有这些ModelBinder映射。

这并不是对您问题的直接回答


我们使用稍微不同的方法来处理您遇到的相同问题。我们的控制器接受与持久实体字段逐字段匹配的DTO。然后,我们需要用户创建持久化实体,这些实体将进入数据库。这消除了不必要的接口并锁定了面向公众的API(意味着重命名持久性对象的字段不会破坏我们的客户端代码)。

这里有一些很好的建议,我实际上提出了一个有效的解决方案。然而,我最终得到了一些东西。我只是为我发布的表单数据创建了特定的模型,并使用了默认的模型绑定器


更简单,它允许我捕获不属于我的域模型的数据(如“注释”字段)。

我认为第二个解决方案非常容易自动化(通过代码生成或反射)。嗨,用户10789,你有没有把这个快速的赏金?
ModelBinders.Binders.Add(typeof(IThing), 
            new FactoryModelBinder<RealThing>());
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NewThing([Bind(Exclude = "Id")] IThing thing) {
    // code to process the thing goes here
}