c# - 绑定源的设置和顺序不应该依赖于 HTTP 动词吗?
问题描述
我有点困惑。我有这个签名的动作方法(asp.net core 2.1):
[HttpGet]
public IEnumerable<DeviceTypeDTO> Get(GetDeviceTypeRequest request)
当我提出请求时,我收到 400 错误消息:
需要一个非空的请求正文。
首先,我想了解它为什么停止并且不尝试从查询字符串绑定模型。至少我会在阅读文档后期望这种行为。
顺便说一句,一旦我应用[FromQuery]
属性,一切正常。
其次,为什么它首先尝试从 body 获取数据作为Get
方法?
更新
看起来在推断绑定源之后没有探测其他源。原因是应用[ApiController]
属性。没有它,模型绑定器会尝试从多个来源获取数据。
解决方案
首先,我想了解它为什么停止并且不尝试从查询字符串绑定模型。
该[ApiController]
属性将自定义添加到ASP.NET Core MVC 中使用的应用程序模型。其中一项定制是如何确定模型绑定的来源。对于找到的每个动作,都会调用其中的InferParameterBindingSources
函数ApiBehaviorApplicationModelProvider
,其中包括以下代码:
for (var i = 0; i < actionModel.Parameters.Count; i++)
{
var parameter = actionModel.Parameters[i];
var bindingSource = parameter.BindingInfo?.BindingSource;
if (bindingSource == null)
{
bindingSource = InferBindingSourceForParameter(parameter);
parameter.BindingInfo = parameter.BindingInfo ?? new BindingInfo();
parameter.BindingInfo.BindingSource = bindingSource;
}
}
这里的调用InferBindingSourceForParameter
最相关,其中包括以下代码:
var bindingSource = IsComplexTypeParameter(parameter) ?
BindingSource.Body :
BindingSource.Query;
如上所示,代码检查参数(GetDeviceTypeRequest request
在您的示例中)以查看它是否复杂(在您的示例中)。鉴于它实际上很复杂,该参数被配置为从请求的正文中使用。
其次,为什么 Get 方法首先尝试从 body 获取数据?
由于这一切都是作为配置 ASP.NET Core MVC 应用程序模型的一部分运行的,因此没有动态上下文来确定这是 GET 还是 POST 请求。话虽如此,我想使用[HttpGet]
操作本身的属性来确定请求将是 GET 请求很容易,但我不能确定它是否那么简单。这可能会在 GitHub 上作为 ASP.NET Core MVC 的问题提出,但这将是一个重大更改。
推荐阅读
- python - 如何迭代,以便在字典中添加唯一值(Python)
- angular - 为 Angular 创建 mat-tree 和一些麻烦
- c# - Enumerable.Repeat 在初始化 List<> 时使用 for 循环表现不佳
- git - GIT - 如何将发行说明放入标签
- angular - 如何动态绑定img和video标签中的图像和视频
- pytorch - 预期输入 batch_size (18) 与目标 batch_size (6) 匹配
- centos - 找不到 glibc 的调试信息
- pytorch - Pytorch 中的所有算子都支持反向传播吗?
- r - 在 rmarkdown 文件的 html 输出中在 for 循环内渲染 tmap 映射
- python - 净现值 - Numpy 与 Excel