2

所以我有一个动作方法需要一个花哨的Cart对象:

[HttpPost]
public JsonResult BuildTransaction(Cart cart) { }

Cart型号:

public class Cart
{
    public Guid UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Address Address { get; set; }
}

我在路由上扔了一些 JSON,看起来像这样:

object cart = new {
            UserId = uid,
            FirstName = "John",
            LastName = "Travlota",                
            Address = new {
                Line1 = "Ramsdean Grange",
                Town = "boom town",
                PostCode = "dd7 7sx"
            }                
        };
var request = client.PostAsJsonAsync("BuildTransaction", cart);

结果,我的控制器中有一个 Cart 类型的购物车可以玩。极好的!

我的问题是,.NET 如何进行这种映射?我想象它在某个地方,OnActionExecute但它是做什么/如何做到这一点的。

如果我想模仿这个功能,我会怎么做?如果没有 MVC 似乎完全有能力做到这一点,我真的需要像 AutoMapper 这样的外部工具吗?

4

4 回答 4

1

首先 MVC 收到一个帖子(例如),其中包含您的 htmlinput值以及name与它们中的每一个关联的值。

然后它检查预期对象(模型类型)中的属性,并尝试name在收到的表单中找到匹配的对象,依此类推。

这一切都发生在 中ModelBinder,您甚至可以更改它的完成方式,因为这是一个扩展点。

所以这是关于如何使用 AutoMapper 的,你在这里不需要它。

于 2013-05-31T14:07:25.273 回答
1

这是由Model Binder完成的。( System.Web.Mvc.DefaultModelBinder)

您可以像这样实现自定义模型绑定器:

控制器:

public ActionResult Create([ModelBinder(typeof(CreateModelBinder))] CreateViewModel   vModel)
{

}

模型粘合剂:

public class CreateModelBinder : DefaultModelBinder
{
     public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
     {
          //assign request parameters here, and return a CreateViewModel
          //for example
          CreateViewModel cVM = new CreateViewModel();
          cVM.Name = controllerContext.HttpContext.Request.Params["Name"];
          return cVM;

     }
}

更多信息:http ://www.dotnetcurry.com/ShowArticle.aspx ?ID=584 https://stackoverflow.com/a/1249602/1324019

于 2013-05-31T14:06:15.037 回答
1

这是 Mvc 模型绑定。MVC 有一组默认的模型绑定器。它使用该DefaultModelBinder对象作为您的发布请求的默认对象,但它还默认注册了以下 3 个对象。

  • HttpPostedFiledModelBinder
  • ByteArrayModelBinder
  • LinqBinaryModelBinder

正如@Mansfield 指出的那样,您还可以创建自己的活页夹并将它们与具有参数属性的参数相关联。但是您也可以为特定类型全局注册它们,如下所示(Application_Start例如)

  //Register FooModelBinder for all posted objects that are of type Foo
  ModelBinders.Binders.Add(typeof(Foo),new FooModelBinder());

如果由于某种原因您想重新发明轮子,您还可以更改 de DefaultModelBinder

ModelBinders.Binders.DefaultBinder = new CustomDefaultModelBinder();

这是 Foo 类型的 ModelBinder 的一个非常简单的实现

public class FooModelBinder: IModelBinder
{
    #region IModelBinder Members

    public object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) {

        IUnvalidatedValueProvider provider = (IUnvalidatedValueProvider)bindingContext.ValueProvider;
        return new Foo {
            Bar = provider.GetValue("Bar", true).AttemptedValue,
            Banana= provider.GetValue("Banana", true).AttemptedValue
        };

    }

    #endregion
}
于 2013-05-31T14:19:19.867 回答
0

ASP.NET MVC 模型绑定器将请求参数转换为类实例。这个伟大的功能基于约定运行,所以只要您遵循默认约定(这意味着您的请求参数需要与您的类的属性名称相同)。所以是的,在大多数情况下,默认模型绑定器行为很好,您不需要像 AutoMapper 这样的库。

如果您想了解更多关于模型绑定何时发生的信息,本文将详细介绍 MVC 管道。如果您只想了解更多关于模型绑定的信息,我发现这个两页教程很有帮助:第 1部分和第 2 部分

于 2013-05-31T14:14:47.673 回答