ASP.NET Core MVC 模型绑定用法及原理

技术ASP.NET Core MVC 模型绑定用法及原理 ASP.NET Core MVC 模型绑定用法及原理https://www.cnblogs.com/savorboard/p/aspnetcor

ASP.NET核心MVC模型绑定的用法和原理

https://www . cn blogs.com/savorboard/p/aspnetcore-model binding . html

前言

我查询了MVC中的模型绑定,主要是如何使用,以及模型绑定过程中的一些用法和概念。很少有关于模型绑定内部机制实现的文章。本文将解释如何在ASP.NET核心MVC中实现模型绑定以及它的一些其他用途。

模型绑定的用途

通常我们在使用MVC框架的时候,不需要关注模型绑定的相关功能,因为它是集成到MVC框架中的。当我们在浏览器中访问一个地址时,无论是GET还是POST访问,MVC框架在映射到Action的过程中都有自动绑定的对象或路由参数,这就是我们使用的模型绑定。

在ASP.NET核心MVC中,模型绑定分为简单模型绑定和复杂模型绑定。简单的模型绑定,比如直接从表单或者URL路由数据中获取inFormation,然后应用到Action方法的每个参数中,如果是复杂的模型绑定,可能不会简单地转换为参数的值,还可能涉及到一些数据类型转换、模型分解、参数验证等。

让我们看一个模型绑定的例子:

假设我们有一个名为Person的ViewModel对象,其代码如下:

公共类人员

{

公共字符串名称{ get设置;}

public int Age { get设置;}

}

在这个视图模型对象中,使用了一些非常简单的类型,因此我们的操作定义如下:

公共类人员控制器

{

[HttpSet]

[路线(' ~ API/人员/添加')]

公共机构结果创建人(人员)

{

返回Ok(人);

}

}

在上面的代码中,我们可以向http://localhost :5000/API/Person/add的地址发送POST请求。身体类型使用普通的形式,参数使用上面的人定义的姓名、年龄和年龄。给Action添加一个断点,我们可以看到person变量中的值,然后Action会返回一个json序列化的结果对象。

这样的过程是模型绑定在实际开发中的目的和用途。

看起来简单吗?但是在内部模型中,绑定子系统是复杂的,由许多部分组成。

模型绑定的一些用法

在ASP.NET核心MVC中,支持以下表单类型的模型绑定。

[FromHeader],[FromQuery],[FromRoute],[FromForm]

示例:

公共机构结果创建人([FromForm]Person)

{

返回Ok(人);

}

这些[FromXXX]告诉模型绑定在解析期间从HttpContext的哪个部分获取信息。

一些模型绑定框架中定义的一些属性被用来限制或忽略模型建模过程中的一些参数。例如

[BindRequired],[BindNever]

这两个是模型绑定过程中增加的一些约束。BindRequired可以应用于类或属性,以限制绑定过程中必须需要的一些值。BindNever用于忽略当前参数的绑定。

还有两个【来自服务】和【来自身体】。

[FromServices]是参数绑定的过程,它告诉模型绑定框架参数是从DI容器中获取的。

[FromBody]是参数绑定的过程,它告诉框架使用配置的格式化程序从Http Body解析参数。

在[FromBody]中,默认使用MVC框。

架内部配置的 JsonInputFormatter 进行反序列化解析,如果你传递的 Body 中的类型是 application/xml,你可以在 ConfigureServices 方法中配置services.AddMvc().AddXmlSerializerFormatters();进行XML的反序列化。

还有一个[ModelBinder]这个可能很多人没用过,这个是应用在 Controller 中的属性上的,用来绑定属性信息。比如

public class Controller
{
    [ModelBinder]
    public string Name { get; set;}
    
    public IActionResult CreatePerson(Person person)
    {
        return Ok(person);
    }
}

在 Action 激活的时候,Controller 的 Name 属性也会具有Action 参数中 person 变量中名字和 Name 相同参数的值。

自定义模型绑定

自定义模型绑定属于 MVC 模型绑定的一些高级知识,在一些特殊情况中我们可能会使用到他们。 详情可以参考这篇 文章https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding,本文不打算做过多介绍。

MVC 模型绑定(ModelBinding)实现原理

看过我ASP.NET Core MVC Action 激活这篇文章的同学应该知道,在 Action 激活的过程中会涉及到很多状态,那么模型绑定是在ActionBegin这个状态中进行的,同时在ActionNext过程中被使用,我就直接接着这篇文章的 Action 执行部分进行讲解了。

首先,模型绑定的入口位于ControllerActionInvoker这个类中的一个Next方法里

private Task Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted){
    ......
    
    switch (next)
    {
        case State.ActionBegin:
             BindArgumentsAsync();
             goto case State.ActionNext;
        
        case State.ActionNext:
            _actionExecutingContext = new ActionExecutingContext(_arguments);
    }
    
    ......
}

可以看到在State.ActionBegin这个过程中使用了BindArgumentsAsync()进行参数绑定,那么整个绑定过程就由此开始。

在 Core MVC 框架模型绑定部分源码中,模型绑定源码分为这几部分:元数据(Metadata),值提供器(ValueProvider),验证者(Validator),绑定器(Binder)

元数据:元数据相当于模型绑定中的实体对象,用来储存在整个模型绑定子系统中需要的各种必要信息和元数据信息,包括模型参数的元数据和以及绑定信息的元数据等等。

值提供器:值提供器用来提供在运行时模型绑定器可以从中提取值的一个Provider, 默认情况下,值提供器会从以下地方提取各种资源的值:

1、以前绑定的操作参数(当该操作为子操作时)

2、表单字段 (FormValueProvider)

3、路由数据 (RouteValueProvider)

4、查询字符串参数 (QueryStringValueProvider)

5、JQuery 表单数据(JQueryFormValueProvider)

这些 ValueProvider 对象由CompositeValueProvider进行统一管理,它是一个集合用来创建或者获取这些 ValueProvider 对象。

验证者:验证者是用来验证Action参数中模型字段的合法性。

它的默认实现是DefaultObjectValidator,它会根据元数据信息来确定绑定过程中使用的具体 ValudatorProvider 对象,ValudatorProvider 是用来提供IModelValidator接口实例对象的。

在 ASP.NET Core MVC 中有两个类实现了IModelValidator接口,他们分别是DataAnnotationsModelValidatorValidatableObjectAdapter。 其中ValidatableObjectAdapter是一个适配器,用来转换和封装验证结果,所以我们主要看DataAnnotationsModelValidator

DataAnnotationsModelValidator就是用来验证模型类中的各种 Attribute 的,也就是DataAnnotations相关的那些类,比如[MaxLength][Required][RegularExpression]等等。

绑定器: 绑定器用来绑定Action参数中的大多数简单和复杂的数据模型,它通过对模型各个属性使用递归逻辑来实现该目标。

针对不同类型的绑定具有不同的绑定器,如:

ArrayModelBinderSimpleTypeModelBinderFormFileModelBinder
FormCollectionModelBinderComplexTypeModelBinder
BodyModelBinderHeaderModelBinderDictionaryModelBinder
ServicesModelBinderKeyValuePairModelBinderByteArrayModelBinder
CancellationTokenModelBinderCollectionModelBinderBinderTypeModelBinder

这些 ModelBinder 对象都具有各自的 Provider 对象,对来返回当前Binder对象的实例对象。

这些 ModelBinder 对象由ParameterBinder进行统一管理,ParameterBinder对象会接收模型的元数据信息(Metadata),绑定器工厂(BinderFactory),验证者(Validator),然后进行最终的模型绑定流程,如下图:

回到总流程

我们回到ControllerActionInvoker这个中,BindArgumentsCoreAsync这个函数中会进行上层的模型绑定,流程如下:

以上总流程的前两步就是 MVC Core 模型绑定系统针对于 Controller 中 Action 参数的绑定,实际上除了针对 Action 参数绑定外,还会对 Controller 中的使用了[IModelBinder]特性的进行绑定,那么第三步就是在做这个事情。

至此,模型绑定流程结束。

总结

在本篇中,我们学习了在 ASP.NET Core MVC 中模型绑定的一些用途和一些基本的用法,然后学习了 MVC框架中模型绑定的一些内部实现原理,通过这个学习我们可以对整个模型绑定系统更加的系统的一个了解,以便于我们有在工作系统的时候可以针对于模型绑定系统进行扩展。

如果你觉得本篇博客对你有帮助的话,感谢您的【推荐】。

如果你对 ASP.NET Core 有兴趣的话可以关注我,我会定期的在博客分享我的学习心得。

转https://www.cnblogs.com/savorboard/p/aspnetcore-modelbinding.html

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/79565.html

(0)

相关推荐

  • JDK7与JDK8中HashMap的实现是怎样的

    技术JDK7与JDK8中HashMap的实现是怎样的本篇文章为大家展示了JDK7与JDK8中HashMap的实现是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。JDK7中的

    攻略 2021年11月16日
  • wcf核心技术书籍(wcf框架入门教程)

    技术WCF开源地带举例分析这篇文章主要讲解了“WCF开源地带举例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“WCF开源地带举例分析”吧!准备:1、安装.NET Fr

    攻略 2021年12月14日
  • 租用香港服务器从事游戏相关业务有什么好处

    技术租用香港服务器从事游戏相关业务有什么好处香港服务器提供了部署所需游戏的灵活性和能力。它可以多方面提升游戏体验,并通过丰富的资源为您的服务器提供更好的安全性,因为您是独享硬件配置的。这可能解释了为什么现代游戏玩家和主播

    礼包 2021年12月21日
  • 一个龙一个天,赤须龙母是个怎么样的神仙

    技术一个龙一个天,赤须龙母是个怎么样的神仙传说一(白族)   相传,龙母原是一个砍柴姑娘,跟妈妈住在绿桃村耪田种庄稼。一年,腾越坎子凹的黑龙占据了洱海的出水口,把大理变成一片汪洋。老百姓无法安生,纷纷逃往外地。母女俩无人

    生活 2021年10月20日
  • 如何搭建动态IP池

    技术如何搭建动态IP池本篇文章给大家分享的是有关如何搭建动态IP池,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。DynamicIP是指在需要时分配IP地址的

    攻略 2021年11月4日
  • hot的比较级,形容词比较级双写+er的有哪些

    技术hot的比较级,形容词比较级双写+er的有哪些在重读闭音节(即:辅音+元音+辅音)中hot的比较级,要双写结尾的辅音字母,然后比较级加er,列举如下:bigger,thinner,fatter,hotter,slim

    生活 2021年10月29日