ASP.NET Core 十九. Action参数的映射与模型绑定(上)

简介: 前文说道了Action的激活,这里有个关键的操作就是Action参数的映射与模型绑定,这里即涉及到简单的string、int等类型,也包含Json等复杂类型,本文详细分享一下这一过程。

一、概述

 当客户端发出一个请求的时候,参数可能存在于URL中也可能是在请求的Body中,而参数类型也大不相同,可能是简单类型的参数,如字符串、整数或浮点数,也可能是复杂类型的参数,比如常见的Json、XML等,这些事怎么与目标Action的参数关联在一起并赋值的呢?


 故事依然是发生在通过路由确定了被请求的Action之后,invoker的创建与执行阶段(详见Action的执行)。


      invoker的创建阶段,创建处理方法,并根据目标Action的actionDescriptor获取到它的所有参数,分析各个参数的类型确定对应参数的绑定方法,


      invoker的执行阶段,调用处理方法,遍历参数逐一进行赋值。


       为了方便描述,创建一个测试Action如下,它有两个参数,下文以此为例进行描述。:

        public JsonResult Test([FromBody]User user,string note = "FlyLolo")
        {
            return new JsonResult(user.Code + "|" + user.Name );
        }

二、准备阶段

  1. 创建绑定方法

 当收到请求后,由路由系统确定了被访问的目标Action是我们定义的Test方法, 这时进入invoker的创建阶段,前文说过它有一个关键属性cacheEntry是由多个对象组装而成(发生在ControllerActionInvokerCache的GetCachedResult方法中),其中一个是propertyBinderFactory:

var propertyBinderFactory = ControllerBinderDelegateProvider.CreateBinderDelegate(_parameterBinder,_modelBinderFactory,_modelMetadataProvider,actionDescriptor,_mvcOptions);

看一下CreateBinderDelegate这个方法:

public static ControllerBinderDelegate CreateBinderDelegate(ParameterBinder parameterBinder,IModelBinderFactory modelBinderFactory,
              IModelMetadataProvider modelMetadataProvider, ControllerActionDescriptor actionDescriptor,  MvcOptions mvcOptions)
{
    //各种验证  略
    var parameterBindingInfo = GetParameterBindingInfo(modelBinderFactory,  modelMetadataProvider, actionDescriptor, mvcOptions);
    var propertyBindingInfo = GetPropertyBindingInfo(modelBinderFactory, modelMetadataProvider, actionDescriptor);
    if (parameterBindingInfo == null && propertyBindingInfo == null)
    {
        return null;
    }
    return Bind;
    async Task Bind(ControllerContext controllerContext, object controller, Dictionary<string, object> arguments)
    {
        //后文详细描述
    }
 }

   前文说过,invoker的创建阶段就是创建一些关键对象和一些用于执行的方法,而propertyBinderFactory 就是众多方法之中的一个,前文介绍它是一个用于参数绑定的Task,而没有详细说明,现在可以知道它被定义为一个名为Bind的Task,最终作为invoker的一部分等待被执行进行参数绑定。


   2. 为每个参数匹配Binder

     上面的CreateBinderDelegate方法创建了两个对象parameterBindingInfo 和propertyBindingInfo ,顾名思义,一个用于参数一个用于属性。看一下parameterBindingInfo 的创建:

private static BinderItem[] GetParameterBindingInfo(IModelBinderFactory modelBinderFactory,IModelMetadataProvider modelMetadataProvider,ControllerActionDescriptor actionDescriptor, MvcOptions mvcOptions)
        {
            var parameters = actionDescriptor.Parameters;
            if (parameters.Count == 0)
            {
                return null;
            }
            var parameterBindingInfo = new BinderItem[parameters.Count];
            for (var i = 0; i < parameters.Count; i++)
            {
                var parameter = parameters[i];
          //略。。。
                var binder = modelBinderFactory.CreateBinder(new ModelBinderFactoryContext
                {
                    BindingInfo = parameter.BindingInfo,
                    Metadata = metadata,
                    CacheToken = parameter,
                });
                parameterBindingInfo[i] = new BinderItem(binder, metadata);
            }
            return parameterBindingInfo;
        }

可以看到parameterBindingInfo 本质是一个BinderItem[]

        private readonly struct BinderItem
        {
            public BinderItem(IModelBinder modelBinder, ModelMetadata modelMetadata)
            {
                ModelBinder = modelBinder;
                ModelMetadata = modelMetadata;
            }
            public IModelBinder ModelBinder { get; }
            public ModelMetadata ModelMetadata { get; }
        }


目录
相关文章
|
16天前
|
数据可视化 网络协议 C#
C#/.NET/.NET Core优秀项目和框架2024年3月简报
公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项目和框架源码地址)。注意:排名不分先后,都是十分优秀的开源项目和框架,每周定期更新分享(欢迎关注公众号:追逐时光者,第一时间获取每周精选分享资讯🔔)。
|
3月前
|
开发框架 前端开发 JavaScript
盘点72个ASP.NET Core源码Net爱好者不容错过
盘点72个ASP.NET Core源码Net爱好者不容错过
71 0
|
1月前
|
开发框架 人工智能 .NET
C#/.NET/.NET Core拾遗补漏合集(持续更新)
C#/.NET/.NET Core拾遗补漏合集(持续更新)
|
1月前
|
开发框架 中间件 .NET
C# .NET面试系列七:ASP.NET Core
## 第一部分:ASP.NET Core #### 1. 如何在 controller 中注入 service? 在.NET中,在ASP.NET Core应用程序中的Controller中注入服务通常使用<u>依赖注入(Dependency Injection)</u>来实现。以下是一些步骤,说明如何在Controller中注入服务: 1、创建服务 首先,确保你已经在应用程序中注册了服务。这通常在Startup.cs文件的ConfigureServices方法中完成。例如: ```c# services.AddScoped<IMyService, MyService>(); //
63 0
|
2月前
|
开发框架 前端开发 .NET
福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!
为了便于大家查找,特将之前开发的.Net Core相关的五大案例整理成文,共计440页,32w字,免费提供给大家,文章底部有PDF下载链接。
33 1
福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!
|
2月前
|
算法 BI API
C#/.NET/.NET Core优秀项目和框架2024年1月简报
C#/.NET/.NET Core优秀项目和框架2024年1月简报
|
2月前
|
机器学习/深度学习 存储 编解码
多任务学习新篇章 | EMA-Net利用Cross-Task Affinity实现参数高效的高性能预测
多任务学习新篇章 | EMA-Net利用Cross-Task Affinity实现参数高效的高性能预测
42 0
|
3月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
41 0
|
1月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
29 0