当前位置:网站首页>1 句代码,搞定 ASP.NET Core 绑定多个源到同一个类
1 句代码,搞定 ASP.NET Core 绑定多个源到同一个类
2022-07-29 04:44:00 【dotNET跨平台】
问题
有群友希望将路由中的信息绑定到一个Dto对象中:
public class DDDDDto
{
[FromRoute(Name ="collectionId")]
public Guid collectionId { get; set; }
[BindProperty(Name = "relativeUrl")]
public string relativeUrl { get; set; }
}这样就不用在 Action 中定义一堆参数了:
[HttpGet("collections/{collectionId}/patn/{relativeUrl}/children", Name = "QueryChildrenOfItem")]
public async Task<DDDDDto> QueryChildren(
[FromRoute(Name = "collectionId")] Guid collectionId,
[FromRoute(Name = "relativeUrl")] string relativeUrl)想法很好,对吧!
但是实际运行,却发现达不到想要的效果,没有绑定到数据:

这说明 ASP.NET Core 默认是无法将其他不同的源绑定到单个类的。
那能不能换种方式,解决这个问题呢?
源码探究
首先,我们查看源码,想看看FromRouteAttribute是如何工作的。
仅在InferParameterBindingInfoConvention类中找到一处调用:
var message = Resources.FormatApiController_MultipleBodyParametersFound(
action.DisplayName,
nameof(FromQueryAttribute),
nameof(FromRouteAttribute),
nameof(FromBodyAttribute));
message += Environment.NewLine + parameters;
throw new InvalidOperationException(message);结果,这段代码还是用来生成异常信息的!?
不过,这段代码前面的部分引起了我们的注意:

这明显是在设置绑定源信息:
bindingSource = InferBindingSourceForParameter(parameter);
parameter.BindingInfo = parameter.BindingInfo ?? new BindingInfo();
parameter.BindingInfo.BindingSource = bindingSource;InferBindingSourceForParameter的实现代码如下:
internal BindingSource InferBindingSourceForParameter(ParameterModel parameter)
{
if (IsComplexTypeParameter(parameter))
{
if (_serviceProviderIsService?.IsService(parameter.ParameterType) is true)
{
return BindingSource.Services;
}
return BindingSource.Body;
}
if (ParameterExistsInAnyRoute(parameter.Action, parameter.ParameterName))
{
return BindingSource.Path;
}
return BindingSource.Query;
}单个类肯定是IsComplexTypeParameter, 这将让方法返回BindingSource.Body。
这也正好解释了: 正常情况下,如果使用单个类作为 Action 参数,默认从 Body 源绑定的原因。
那么,能否改变 ASP.NET Core 这一默认的绑定行为吗?
柳暗花明
继续查看InferParameterBindingInfoConvention的使用,我们发现它的调用,居然在一个条件分支内:
if (!options.SuppressInferBindingSourcesForParameters)
{
var serviceProviderIsService = serviceProvider.GetService<IServiceProviderIsService>();
var convention = options.DisableImplicitFromServicesParameters || serviceProviderIsService is null ?
new InferParameterBindingInfoConvention(modelMetadataProvider) :
new InferParameterBindingInfoConvention(modelMetadataProvider, serviceProviderIsService);
ActionModelConventions.Add(convention);
}那么,如果让SuppressInferBindingSourcesForParameters设为true,会有什么效果呢?
builder.Services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressInferBindingSourcesForParameters = true;
});下面,就是见证奇迹的时刻:

我们也尝试了从其他源,比如 Query,传递数据,都可以正常绑定。
1 句代码,我们搞定了 ASP.NET Core 将多个来源绑定到同一个类的功能。
结论
后来,我们在官方文档(https://docs.microsoft.com/zh-cn/aspnet/core/web-api/?view=aspnetcore-6.0)找到了解释:

当没有在参数上显式指定[FromXXX]时,ASP.NET Core 会进行绑定源推理,比如会推断单个类的绑定源为 Body。
设置 SuppressInferBindingSourcesForParameter 为 true,则会禁用绑定源推理。ASP.NET Core 运行时会尝试按顺序从所有源中拉取数据进行绑定。
添加微信号【MyIO666】,邀你加入技术交流群
边栏推荐
- Ethernet of network
- Introduction to auto.js script development
- Pyscript cannot import package
- Implementation of flutter gesture monitoring and Sketchpad
- PHP判断用户是否已经登录,如果登录则显示首页,如果未登录则进入登录页面或注册页面
- pyscript无法引入包
- Dasctf2022.07 empowerment competition
- 数据湖:分布式开源处理引擎Spark
- Understand the Internet giant [the war between China and Taiwan] and the development thinking of China and Taiwan
- Classes and objects (II)
猜你喜欢

Dasctf2022.07 empowerment competition

Take you to understand JS array
![学术 | [LaTex]超详细Texlive2022+Tex Studio下载安装配置](/img/4d/f8c60c0fbbd98c4da198cfac7989fa.png)
学术 | [LaTex]超详细Texlive2022+Tex Studio下载安装配置

Mujoco and mujoco_ Install libxcursor.so 1:NO such dictionary

Reveal installation configuration debugging

网络之以太网

命令行交互工具(最新版) inquirer 实用教程

un7.28:redis客户端常用命令。

Actual combat of flutter - DIO of request encapsulation (II)

UE plays video in scene or UMG
随机推荐
Makefile+make Basics
Reveal安装配置调试
[c language] use the reverse order output of the linked list (bidirectional linked list)
i++与++i详解
Implementation of flutter gesture monitoring and Sketchpad
Recommendation system of online education
Laya中的A星寻路
Google browser opens the web page and out of memory appears
un7.28:redis客户端常用命令。
Go面向并发的内存模型
Dasctf2022.07 empowerment competition
LeetCode_ Stack topics
(heap sort) heap sort is super detailed, I don't believe you can't (C language code implementation)
Star a pathfinding in LAYA
Corresponding order of 18 and 25coco data of openpose and joint points
String, array, generalized table (detailed)
Leetcode (Sword finger offer) - 53 - I. find the number I in the sorted array
Hengxing Ketong invites you to the 24th China expressway informatization conference and technical product exhibition in Hunan
[c language] PTA 7-50 output Fahrenheit Celsius temperature conversion table
Oracle 插入数据