专栏首页me的随笔ASP.NET MVC5 ModelBinder

ASP.NET MVC5 ModelBinder

什么是ModelBinding

ASP.NET MVC中,所有的请求最终都会到达某个Controller中的某个Action并由该Action负责具体的处理和响应。为了能够正确处理请求,Action的参数(如果有的话),必须在Action执行之前,根据相应的规则,把请求中所包含的数据提取出来并将映射为Action的参数值,这个过程就是ModelBinding。ModelBinding的作用就是为Action提供参数列表。

ModelBinding的好处

  1. 使代码变得更加简洁
  2. 帮助我们获取HTTP请求中的数据
  3. 帮助我们完成必要的数据类型转换

ASP.NET MVC中ModelBinding的实现过程

ASP.NET MVC中ModelBinding的实现过程比较复杂,这里简要说明它的总体流程。具体的实现过程可以看蒋金楠的《ASP.NET MVC5框架揭秘》或者看他的博客How ASP.NET MVC Works?,讲解很详细。

  • HTTP请求中的数据可能存在于querystring中,也可能在表单中,也有可能是JSON字符串。究竟从哪里获取数据,这要依赖于参数的描述信息ParameterDescriptor
  • ParameterDescriptor的获取需要借助于ControllerDescriptorActionDescriptor,它们分别用来描述Controller和Action
  • IModelBinderProvider用于提供合适的ModelBinder对象,我们可以自己实现该接口以获取自定义的IModelBinder
  • ModelBinding的核心IModelBinder,默认实现类是DefaultModelBinder,我们可以自己实现IModelBinder接口来扩展ModelBinder
  • IValueProvider针对不同的数据源提供了数据的访问机制
  • ValueProviderResult提供了两个ConvertTo方法重载以实现向指定目标类型的转换。
  • 经过上述一系列的处理获取最终结果

自定义ModelBinder

自定义Modelbinder只需实现System.Web.Mvc.IModelBinder接口即可。这里需要注意一点,System.Web.ModelBinding命名空间下也有一个IModelBinder接口,不要搞错了。

public class LessonEditInfoViewModelBinder : IModelBinder
{
    //根据前台传递的id值获取对象
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var idStr = controllerContext.HttpContext.Request["id"] ?? controllerContext.RouteData.Values["id"]?.ToString();
        int id = 0;
        if (!int.TryParse(idStr, out id))
        {
            return null;
        }
        var model = new LessonBLL().GetLessonEditInfo(id);
        return model;
    }
}

然后使用ModelBinderAttribute进行标注即可:

/*
    根据前台传递的id值解析出对象数据,Action无需关注对象的获取,使代码变得清晰简洁
*/
public ActionResult Edit([ModelBinder(typeof(LessonEditInfoViewModelBinder))]LessonEditInfoViewModel lesson)
{
    if (lesson == null)
    {
        //跨控制器的视图跳转要使用视图的路径+文件名
        return View("/Views/Exception/GenericError.cshtml", new ExceptionViewModel { Title = "404", Description = "课程不存在!" });
    }
    return View(lesson);
}

如果项目中多处需要使用自定义的ModelBinder,那么再使用ModelBinderAttribute进行标注就不大合适了。这种情况我们可以使用自定义的ModelBinderProvier。代码如下:

public class CustomeModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(Type modelType)
    {
        if (modelType == typeof(LessonEditInfoViewModel))
        {
            return new LessonEditInfoViewModelBinder();
        }
        return null;
    }
}

然后将自定义的ModelBinderProvider注册到ASP.NET MVC系统中

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ModelBinderProviders.BinderProviders.Insert(0, new CustomeModelBinderProvider());
    }
}

完成上述两步之后,就无需使用ModelBuilderAttribute进行标注了。

除此之外,还可在Global文件中使用使用ModelBinder类的Binder属性来注册ModelBinderProvider

ModelBinders.Binders.Add(typeof(LessonEditInfoViewModel),new LessonEditInfoViewModelBinder());

不同的ModelBinder提供策略有不同的优先级,具体如下:

  1. 在参数上使用CustomModelBinderAttribute
  2. 使用ModelBinderProviders.BinderProviers
  3. 使用ModelBinders.Binders
  4. 参数类型上标记CustomModelBinderAttribute
  5. ASP.NET MVC中提供的DefaultModelBinder

注意,CustomModelBinderAttribute是抽象类,在ASP.NET MVC中有唯一子类ModelBinderAttribute。

参考文章:

Model Binders in ASP.NET MVC ModelBinder——ASP.NET MVC Model绑定的核心 ASP.NET MVC以ValueProvider为核心的值提供系统 玩转Asp.net MVC 的八个扩展点 ASP.NET MVC中你必须知道的13个扩展点

版权声明

本文为作者原创,版权归作者雪飞鸿所有。 转载必须保留文章的完整性,且在页面明显位置处标明原文链接

如有问题, 请发送邮件和作者联系。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ASP.NET MVC5请求管道和生命周期

    请求管道是一些用于处理HTTP请求的模块组合,在ASP.NET中,请求管道有两个核心组件:IHttpModule和IHttpHandler。所有的HTTP请求都...

    雪飞鸿
  • ASP.NET Web API 2中的错误处理

    前几天在webapi项目中遇到一个问题:Controller构造函数中抛出异常时全局过滤器捕获不到,于是网搜一把写下这篇博客作为总结。

    雪飞鸿
  • .NET Core中的包、元包与框架

    .NET Core是一个由NuGet包组成的平台。一些产品受益于细粒度包的定义,也有一些受益于粗粒度包的定义。为了适应这种二重性,.NET Core平台被分为一...

    雪飞鸿
  • 为什么 web 开发人员需要迁移到. NET Core, 并使用 ASP.NET Core MVC 构建 web 和 webservice/API

    张善友
  • 为什么 web 开发人员需要迁移到. NET Core, 并使用 ASP.NET Core MVC 构建 web 和 webservice/API

    如果你是一个初学者开始学习 ASP.NET 或 ASP.NET MVC, 你可能并不知道什么是. net Framework和. net ore。不用担心!我建...

    张善友
  • [翻译] ASP.NET Core 3.0 的新增功能

    全文翻译自微软官方文档英文版 What's new in ASP.NET Core 3.0

    梁规晓
  • .NET Core 学习资料精选:入门

    本系列文章,主要分享一些.NET Core比较优秀的社区资料和微软官方资料。我进行了知识点归类,让大家可以更清晰的学习.NET Core。

    梁规晓
  • 极简版ASP.NET Core学习路径及教程

    绝承认这是一个七天速成教程,即使有这个效果,我也不愿意接受这个名字。嗯。 视频系列已出: http://www.cnblogs.com/jesse2013/p/...

    用户1153966
  • 《从零开始学ASP.NET CORE MVC》课程介绍(一)

    大家好,欢迎来到52ABP学院,收看我们的 《从零开始学ASP.NET CORE MVC》。

    角落的白板报
  • .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了

    很多朋友看到.NET Core就认为是ASP.NET Core,其实这是有误区的,因为.NET Core 是开放源代码的通用开发平台 (是一个“平台”),基于这...

    依乐祝

扫码关注云+社区

领取腾讯云代金券