繁体   English   中英

MVC 5模型绑定器覆盖

[英]MVC 5 Model Binder Override

我写了一个模型Binder的覆盖。

public override object BindModel(Controller context, ModelBindingContext bindingContext)
{
    var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

    object returnVal = null;

    if (value == null)
        returnVal = base.BindModel(controllerContext, bindingContext);
    else
    {
        /* custom logic here that never seems to get called.
            returnVal = something();
        */
    }

    return returnVal;
}

我还有一个javascript服务(在Angular中)向我的一个控制器发出一个AJAX请求。

AJAX请求尝试发布一组int。 我尝试单步执行模型绑定器,似乎value始终为null。 通过一些魔术, base.BindModel()仍然能够将我的集合绑定到正确的C#对象。

这个问题是我不能使用我的自定义绑定器,因为从不调用else块。 除了使用ValueProvider之外,还有其他方法可以获得价值吗?

我也相信在这个自定义绑定器正常工作之前(从内存可能是错误的)。 我最近从4.5更新到5.2.something。 是否有任何更新可以改变这种行为?

我还有一个javascript服务(在Angular中)向我的一个控制器发出一个AJAX请求。

...

这个问题是我不能使用我的自定义绑定器,因为从不调用else块。

  • 我将假设您已在全局或在一个或多个参数上的操作本身上正确注册了活页夹。
  • 我还假设您的活页夹在您预期时被调用。

它为null,因为它无法根据您尝试绑定的模型名称查找数据。 是否可以通过此名称找到该值取决于型号名称和客户端请求中发送的必须对齐/匹配的数据。 但在任何人都可以告诉你为什么它不匹配的数据(包括你的模型与数组)可以通过以下三种方式之一从客户端发送:

  1. 如果使用URL,您将在查询字符串中重用相同的属性名称。 示例: ?myArray=1&myArray=2&myArray=3 这意味着在您的模型绑定器中,您将不得不考虑这一点。
  2. 如果在POST中使用data (正文),那么它可能是一个实际的数组对象。 json中的示例: {"myArray":[1,2,3,4]}
  3. 您可能还要序列化整个表单并使用Angular发送它( 这将允许您更好地使用MVC中的绑定功能

因此,为了更好地回答您的问题,您需要提供

  1. 数据的格式是从浏览器发送的以及它的发送方式(查询字符串或数据有效负载)( 这可能在您的Angular工厂,服务或控制器中
  2. 您要绑定的模型定义

所以回顾一下: bindingContext.ModelName是期望的名称,必须与模型绑定器试图找到的数据匹配。 如果您要发送{"myArray":[1,2,3,4]}但您的模型属性名为ProductIds那么它将始终为null。

我最近从4.5更新到5.2.something

不,不是我知道的。


最后的想法。 您还可以让默认模型绑定器执行,然后在类型匹配时使用返回值执行某些操作。 如果绑定现在没有问题,但你想做一些后处理,这将是一个更好的选择。 例:

public override object BindModel(Controller context, ModelBindingContext bindingContext)
{
    var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

    object returnVal = base.BindModel(controllerContext, bindingContext);

    /* check returnVal and then additional custom logic here */.

    return returnVal;
}

请确保你做过这样的事情: -

  1. 自定义模型绑定: -

     public class HomeCustomDataBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(HomePageModels)) { HttpRequestBase request = controllerContext.HttpContext.Request; string title = request.Form.Get("Title"); string day = request.Form.Get("Day"); string month = request.Form.Get("Month"); string year = request.Form.Get("Year"); return new HomePageModels { Title = title, Date = day + "/" + month + "/" + year }; //// call the default model binder this new binding context //return base.BindModel(controllerContext, newBindingContext); } else { return base.BindModel(controllerContext, bindingContext); } } } 
  2. 一旦我们完成了自定义类的编码,我们将需要在Application_Start()下的Global.asax中注册我所做的类。

     protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); ModelBinders.Binders.Add(typeof(HomePageModels), new HomeCustomBinder()); } 

    3)最后,我们需要告知控制器我们希望它使用的绑定。 我们可以使用属性[ModelBinder(typeof(HomeCustomBinder))]指定如下:

     [HttpPost] public ActionResult Index([ModelBinder(typeof(HomeCustomBinder))] HomePageModels home) { if (ModelState.IsValid) { ViewBag.Title = home.Title; ViewBag.Date = home.Date; } return View(); } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM