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)

相关推荐

  • 兰因絮果是什么意思,与戚戚意思相似的词语是什么

    技术兰因絮果是什么意思,与戚戚意思相似的词语是什么,语文老师一枚,分享一些能替换一般词汇的高级词汇兰因絮果是什么意思: 1.陌上 陌,原来是田间的小路,后来指代一般的路。所以,陌上就是路上的意思。这是一个古典的词语,古人

    生活 2021年10月24日
  • 新加坡云服务器值得租用吗

    技术新加坡云服务器值得租用吗新加坡云服务器提供了一个虚拟和独立的环境来托管您的企业网站。它可以将您的网络业务的文件和数据存储在链接到物理机器或服务器的虚拟环境中。这实际上是通过虚拟化软件完成的。通过虚拟化技术,物理服务器

    礼包 2021年12月8日
  • 分享CSS3边框

    技术分享CSS3边框本篇内容主要讲解“分享CSS3边框”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“分享CSS3边框”吧!浏览器支持实例使用图片创建围绕 div 元素的边框:

    攻略 2021年11月6日
  • mybatis中返回值应该配置什么(mybatis中select方法怎么写)

    技术Mybatis Select Count(*)的返回值类型是什么本篇内容介绍了“Mybatis Select Count(*)的返回值类型是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就

    攻略 2021年12月21日
  • 香港VPS与云服务器:哪个是您的正确选择

    技术香港VPS与云服务器:哪个是您的正确选择与传统香港服务器相比,如果搭建简单的是一些结构简单的小型网站,从成本的角度考虑,香港VPS和香港云服务器都具有明显的优势。但是你如何在它们之间做出选择呢?VPS和云主机一样吗?

    礼包 2021年10月20日
  • 怎么给出一个二叉树python(python如何判断平衡二叉树)

    技术python对称二叉树该如何理解这期内容当中小编将会给大家带来有关python对称二叉树该如何理解,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。题目描述给定一个二叉树,检查它是否是

    攻略 2021年12月13日