当前位置:网站首页>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】,邀你加入技术交流群
边栏推荐
- Pycharm reports an error when connecting to the virtual machine database
- 带你一文理解JS数组
- UE plays video in scene or UMG
- Idea small settings
- 命令行交互工具(最新版) inquirer 实用教程
- Software test interview questions (4)
- Hengxing Ketong invites you to the 24th China expressway informatization conference and technical product exhibition in Hunan
- RecyclerView通过DPAD按键上下切换焦点 切换到界面外的控件时焦点会左右乱跳
- [C language] PTA 7-47 binary leading zero
- Recyclerview switches the focus up and down through the dpad key. When switching to the control outside the interface, the focus will jump left and right
猜你喜欢
(heap sort) heap sort is super detailed, I don't believe you can't (C language code implementation)
安装spinning up教程里与mujoco对应的gym,报错mjpro150
C语言实现三子棋
Christmas tree web page and Christmas tree application
On the use of pyscript (realizing office preview)
Webrtc realizes simple audio and video call function
Reveal installation configuration debugging
用 ZEGO Avatar 做一个虚拟人|虚拟主播直播解决方案
String, array, generalized table (detailed)
MySQL - 聚簇索引和辅助索引
随机推荐
Makefile+Make基础知识
Mongo Shell交互式命令窗口
Pyscript cannot import package
Update learning materials daily
iOS面试准备 - ios篇
un7.28:redis客户端常用命令。
ssm整合增删改查
正确的用户拖拽方式
安装spinning up教程里与mujoco对应的gym,报错mjpro150
Basic operation of queue
How to build a mobile studio network?
Basic grammar of C language
There are objections and puzzles about joinpoint in afterreturning notice (I hope someone will leave a message)
LeetCode(剑指 Offer)- 53 - I. 在排序数组中查找数字 I
IOS interview preparation - Online
盒子水平垂直居中布局(总结)
ios面试准备 - objective-c篇
spinning up安装完使用教程测试是否成功,出现Library“GLU“ not found和‘from pyglet.gl import *错误解决办法
学术 | [LaTex]超详细Texlive2022+Tex Studio下载安装配置
Star a pathfinding in LAYA