我有点困惑。我有带有此签名的操作方法(asp.net core 2.1):
[HttpGet]
public IEnumerable<DeviceTypeDTO> Get(GetDeviceTypeRequest request)
发出请求时,出现400错误消息:
需要一个非空的请求正文。
首先,我想了解为什么它停止并且不尝试从查询字符串绑定模型。至少在阅读doc之后,我会期望这种行为。
顺便说一句,一旦我应用[FromQuery]
属性,一切都会很好。
第二,为什么首先尝试使用Get
方法从主体获取数据?
更新
推断出绑定源后looks like,没有其他任何源被探测。应用[ApiController]
属性的原因。没有模型绑定器会尝试从多个来源获取数据。
答案 0 :(得分:1)
首先,我想了解为什么它停止并且不尝试从查询字符串绑定模型。
[ApiController]
属性将自定义项添加到ASP.NET Core MVC中使用的Application Model中。这些定制之一是如何确定模型绑定的来源。对于找到的每个动作,将调用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方法从正文中获取数据?
由于所有这些操作都是作为配置ASP.NET Core MVC应用程序模型的一部分运行的,因此没有运行中的上下文来确定这是GET还是POST请求。话虽如此,我想使用动作本身上的[HttpGet]
属性来确定该请求将是GET请求就足够容易了,但是我不确定它是否是如此简单。对于ASP.NET Core MVC,这可能是GitHub上的一个问题,但这将是一个重大更改。