Asp.net MVC的Model Binder工作流程以及扩展方法(3) - DefaultModelBinder

Default Binder是MVC中的清道夫,把守着Model Binder中的最后一道防线。如果我们没有使用Custom Model Binder等特殊处理,那么Model的绑定都是有Default Binder处理的。这篇文章,一起看看Default Binder和如何扩展Default Binder.

一,Default Binder的流程

下面的图是Default Model Binder中的关键方法BindModel的代码逻辑图。

ValueProvider是包装好的类似于字典容器,里面包含了所有request中能够获取到的值(无论是Form提交的,还是Querystring中的)

1. 假如我们绑定一个简单的int参数,那么Default Binder会在ValueProvder中直接找到对应值,然后返回。
2. 如果绑定的是复杂类型(图中的Complex Model),比如对象,则会遍历每个属性,然后绑定该属性的值。如果属性是简单类型,就走上面的1流程;如果不是,就继续进行2流程。

可以看出,Default Model Binder是一个比较复杂和巧妙的过程。在扩展Default Binder的时候,如果override BindeModel方法,不会全盘重写,而是一个”修饰“的过程。
另外,在BindeModel过程中,有对于数据的验证的,这是和我们之前介绍的Custom Model Binder和Binder Attribute不同的地方

mvc_default_model_binding_flow

二,覆盖方法,改变Default Binder行为

这里应用stackoverflow上的一个例子。原文地址: http://stackoverflow.com/questions/8729139/manipulate-model-value-before-passing-it-to-defaultmodelbinder-bindmodel

问题: 
input中要求用户输入百分比值,但是不过分限定用户输入值的格式,比如用户可以输入50, 50%, 后台代码希望提交绑定后的值是个decimal类型,也就是说,在用户输入50, 50%的情况下,后台代码得到的是0.5

首先看看,属性是如何定义的。下面代码中的FooPercent 就是我们用来保存百分比的属性。

[DataType("Percent")]
[Display(Name = "Percent of foo completed")]
[Range(0.0d, 1.0d, ErrorMessage="The field {0} must be between {1:P0} and {2:P0}.")]
public decimal? FooPercent { get; set; }

接下来,创建PercentModelBinder继承自DefaultModelBinder. 发现DataType是Percent的绑定对象,会先尝试绑定。

复制代码
public class PercentModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext,
                                     ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelMetadata.DataTypeName == "Percent")
        {
            ValueProviderResult result =
                bindingContext.ValueProvider.GetValue(
                    bindingContext.ModelName);
            if (result != null)
            {
                string stringValue =
                    (string)result.ConvertTo(typeof(string));
                decimal decimalValue;
                if (!string.IsNullOrWhiteSpace(stringValue) &&
                    decimal.TryParse(
                        stringValue.TrimEnd(new char[] { '%', ' ' }),
                        out decimalValue))
                {
                    return decimalValue / 100.0m;
                }
            }
        }
        return base.BindModel(controllerContext, bindingContext);
    }
}
复制代码

最后,替换MVC原有的DefaultModelBinder

protected void Application_Start() 
{
    ModelBinders.Binders.DefaultBinder = new PercentModelBinder ();
}

 



本文转自JustRun博客园博客,原文链接:http://www.cnblogs.com/JustRun1983/p/3639694.html,如需转载请自行联系原作者


来源:https://yq.aliyun.com/articles/388114


智能推荐

ASP.NET MVC 入门3、Routing

原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/03/1303612.html 在一个route中,通过在大括号里放一个占位符来定义( { and } )。当解析URL的时候,符号"/"和"."被作为一个定义符来解析,而定义符之间的值则匹配到占位符中。route定义中不在大括号里的信息则作为常量值。 ...

ASP.NET MVC 验证登录方法

开发工具和关键技术:Visual Studio 2015,ASP.NET MVC 作者:金建勇 撰写时间:2019年4月20日   在做一个项目一个系统的时候,最基本的肯定是得有登录页面的,需要输入账号、密码还有验证码这些登录信息,也当只有输入这些信息正确的时候,才能登录成功。这个时候也就涉及到验证登录了,我们就需要在控制器写上一个方法,用来验证登录时输入的这些信息是否正确,然后在登录的...

ASP.NET MVC 3 Model【通过一简单实例一步一步的介绍】

今天主要讲Model的两个方面: 1. ASP.Net MVC 3 Model 简介 通过一简单的事例一步一步的介绍 2. ASP.Net MVC 3 Model 的一些验证       MVC 中 Model 主要负责维持数据状态,将数据从数据存储器中检索并传递给控制器,客户端传送过来的数据通过处理后再传回数据存储系统中。是MVC中较为重要的一层...

ASP.NET MVC 3 Model【通过一简单实例一步一步的介绍】

今天主要讲Model的两个方面: 1. ASP.Net MVC 3 Model 简介 通过一简单的事例一步一步的介绍 2. ASP.Net MVC 3 Model 的一些验证       MVC 中 Model 主要负责维持数据状态,将数据从数据存储器中检索并传递给控制器,客户端传送过来的数据通过处理后再传回数据存储系统中。是MVC中较为重要的一层...

ASP.NET的MVC请求处理流程

原文地址:ASP.NET的MVC请求处理流程 用户打开浏览器,在地址栏输入某个网址的URL并回车,浏览器便开始像该URL指定的服务器发起HTTP请求 服务器的网站服务系统(IIS)接收到该请求,先检查自己是否认识该类请求,如果认识就直接处理并发回响应,否则就将该类请求发给对应的HTTP处理程序(在此时ASP.NET的MVC) MVC的路由系统接收到该请求,根据HTTP请求的URL,把请求定向到指定...

猜你喜欢

【ASP.NET】ASP.NET MVC 3 & Unity.MVC3

最近学习了下 ASP.NET MVC,比较之前的 WebForm 没有了 IsPostBack 的判断,事件处理也被 Action 取代。MVC 中 WebForm中大量的事件处理中UI绑定,混杂的 js 注入, style 修改没有了;服务端控件不用了,结局是 View 被释放了,Controller可以被单元测试了,拿着 ViewModel 可以快速替换 View。(说句实话要不是有 Razo...

基于IPagedList 的 Asp.Net MVC3 分页

后台对数据的分页 个人最近比较喜欢使用DefaultValue 当然也可以写成 这里ToPagedList 这个扩展方法里第一个参数是index 懒得去改成page了,所以就用了 p-1 前台中调用 样式啥的控制和上一篇差不多我不在这里说了 DEMO中的效果图: DEMO下载:/Files/francis67/MvcDemo.rar...

ASP.NET MVC 3: Razor的@:和语法

来自森大科技官方博客,排版更好! http://www.cnsendblog.com/index.php/?p=115 这是我正在写的博文系列中的另一篇,涵盖ASP.NET MVC 3的一些新功能: http://weblogs.asp.net/scottgu/archive/2010/10/19/asp-net-mvc-3-new-model-directive-support-in-razor...

ASP.NET MVC 3 中 Chart 的使用 Demo

首先在项目中添加对 System.Web.DataVisualization.dll 的引用。 然后在 web.config 中 并且   代码如下: ChatController Simple.cshtml   Primary.cshtml   Middle.cshtml   High.cshtml       运行截图: D...

FDM3D打印技术原理简析

FDM3D打印技术原理简析 FDM(FusedDepositionModeling),熔融定位挤出型的全称,也叫挤压造型。不懂的话,可以想象早上刷牙挤牙膏的感觉,主要组成为工作台;线材;主动辊和从动辊;喷嘴加热区(下方为喷嘴);支撑结构(支撑上方粘连的为我们打印的模型) FDM以丝状供料,材料是一卷一卷的(有点像新冠疫情前期国外超市首先被抢购一空的——厕纸)打印时,材料被加...

问答精选

How to get key, value from list of dictionaries in python

I have a list of dictionaries, i am trying to get key and value of each dictionary to assign into protobuff object. My sample code: My protofile This should work, although it is unclear what you are t...

Overlap relative positioned images in CSS

I made fading slideshow in CSS3. Now I must insert it in a div container in such a way that the slideshow has width 100% of the parent, and appropriate height. If it was a single image I can easily do...

GROUP BY with MAX Date

The source table is: Desired result: How do we obtain it using SQL? I tried But it does not seem to be working. Isn't it like this?...

.NET - Is there a way to change the GC behavior for the entire machine?

A co-worker said this is possible (but it looks a bit strange to me). If there's a way to do it, where can I do this? I'm talking about winXP OS. Yes, the GC has two modes of operation: Server and Wor...

XSLT: select all nodes without inner elements and without attributes

How to select all nodes without inner elements and without attributes in .xml with unknown structure? XPATH expression to find elements without subelements nor attributes is: //[not(|@*)] You will get...

相关问题

相关文章

热门文章

推荐文章

相关标签

推荐问答