当前位置:网站首页>1 sentence of code, get asp Net core binds multiple sources to the same class
1 sentence of code, get asp Net core binds multiple sources to the same class
2022-07-29 04:49:00 【Dotnet cross platform】
problem
A group of friends want to bind the information in the route to a Dto In the object :
public class DDDDDto
{
[FromRoute(Name ="collectionId")]
public Guid collectionId { get; set; }
[BindProperty(Name = "relativeUrl")]
public string relativeUrl { get; set; }
}So there's no need to Action A bunch of parameters are defined in :
[HttpGet("collections/{collectionId}/patn/{relativeUrl}/children", Name = "QueryChildrenOfItem")]
public async Task<DDDDDto> QueryChildren(
[FromRoute(Name = "collectionId")] Guid collectionId,
[FromRoute(Name = "relativeUrl")] string relativeUrl)Good idea. , Right !
But the actual operation , But I found that I couldn't achieve the desired effect , Not bound to data :

This explanation ASP.NET Core By default, you cannot bind other different sources to a single class .
Can you change the way , To solve this problem ?
Source code exploration
First , Let's look at the source code , Want to see FromRouteAttribute How it works .
Only in InferParameterBindingInfoConvention Class found a call :
var message = Resources.FormatApiController_MultipleBodyParametersFound(
action.DisplayName,
nameof(FromQueryAttribute),
nameof(FromRouteAttribute),
nameof(FromBodyAttribute));
message += Environment.NewLine + parameters;
throw new InvalidOperationException(message);result , This code is also used to generate exception information !?
however , The previous part of this code caught our attention :

This is obviously setting the binding source information :
bindingSource = InferBindingSourceForParameter(parameter);
parameter.BindingInfo = parameter.BindingInfo ?? new BindingInfo();
parameter.BindingInfo.BindingSource = bindingSource;InferBindingSourceForParameter The implementation code of is as follows :
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;
} A single class must be IsComplexTypeParameter, This will cause the method to return BindingSource.Body.
This also just explains : Under normal circumstances , If you use a single class as Action Parameters , The default from the Body Reason for source binding .
that , Can you change ASP.NET Core This default binding behavior ?
One good thing came out of
Keep looking at InferParameterBindingInfoConvention Use , We found its call , Actually in a conditional branch :
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);
} that , If you allow SuppressInferBindingSourcesForParameters Set to true, What effect will it have ?
builder.Services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressInferBindingSourcesForParameters = true;
});below , It's a time to witness miracles :

We also tried from other sources , such as Query, To transfer data , Can be bound normally .
1 Sentence code , We've got it ASP.NET Core The ability to bind multiple sources to the same class .
Conclusion
later , We're in the official file (https://docs.microsoft.com/zh-cn/aspnet/core/web-api/?view=aspnetcore-6.0) I found an explanation :

When not explicitly specified on the parameter [FromXXX] when ,ASP.NET Core Can perform binding source reasoning , For example, it will be inferred that the binding source of a single class is Body.
Set up SuppressInferBindingSourcesForParameter by true, Will disable binding source inference .ASP.NET Core The runtime will try to pull data from all sources in order for binding .
Add microsignals 【MyIO666】, Invite you to join the technical exchange group
边栏推荐
- Box horizontal vertical center layout (summary)
- STL source code analysis (Hou Jie) notes -- Classification and testing of stl containers
- SGuard64.exe ACE-Guard Client EXE:造成磁盘经常读写,游戏卡顿,及解决方案
- [c language] PTA 7-51 sum the first n terms of odd part sequence
- GCC基础知识
- 网络之以太网
- C language implementation of three chess
- [c language] use the reverse order output of the linked list (bidirectional linked list)
- MySQL - clustered index and secondary index
- Use of construction methods
猜你喜欢

删除word文档中的空白页

Download addresses of various versions of MySQL and multi version coexistence installation

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

Christmas tree web page and Christmas tree application

2022杭电多校联赛第四场 题解

ios面试准备 - 网络篇

Take you to understand JS array

常见的限流方式

Recommendation system of online education

Implementation of flutter gesture monitoring and Sketchpad
随机推荐
如何避免示波器电流探头损坏
SSM integration, addition, deletion, modification and query
The daily life of programmers
STL source code analysis (Hou Jie) notes -- Classification and testing of stl containers
Deep analysis of data storage in memory (Advanced C language)
数据湖:分布式开源处理引擎Spark
IOS interview preparation - IOS
Mysql:The user specified as a definer (‘root‘@‘%‘) does not exist 的解决办法
C语言之基础语法
LeetCode(剑指 Offer)- 53 - I. 在排序数组中查找数字 I
Classes and objects (I)
On quotation
TypeError: Cannot read properties of undefined (reading ‘then‘)
Makefile+Make基础知识
Update learning materials daily
ios面试准备 - 网络篇
安装spinning up教程里与mujoco对应的gym,报错mjpro150
MySQL - clustered index and secondary index
删除word文档中的空白页
[c language] PTA 7-51 sum the first n terms of odd part sequence