Sim*_*ane 7 asp.net asp.net-core
我喜欢ASP.NET Core 2.1 新的自动 HTTP 400 响应功能,它在大多数情况下都运行良好。
但是,在一个操作中,我需要在验证有效负载之前进行一些预处理。我有一个自定义验证器,它需要模型中的两个值来执行验证。其中一个值在路径中,所以我想从路径中的模型上设置该值然后验证。
我不想关闭所有操作的功能:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
}
Run Code Online (Sandbox Code Playgroud)
有什么办法可以仅针对个人操作将其关闭?
编辑:
我尝试修改 InvalidModelStateResponseFactory 但它没有解决我的问题,因为我仍然需要进入控制器操作:
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory = actionContext =>
{
var ignore = actionContext.ActionDescriptor.FilterDescriptors.Any(fd => fd.Filter is SuppressModelStateInvalidFilterAttribute);
if (ignore)
{
// Can only return IActionResult so doesn't enter the controller action.
}
return new BadRequestObjectResult(actionContext.ModelState);
};
});
[AttributeUsage(AttributeTargets.Method)]
public class SuppressModelStateInvalidFilterAttribute : FormatFilterAttribute
{
}
Run Code Online (Sandbox Code Playgroud)
编辑:
这是我在 asp.net 核心 repo 上提出的问题的链接,以防万一我得到任何地方 - https://github.com/aspnet/Mvc/issues/8575
更新:您可以在 Startup.cs 的 ConfigureServices 中使用以下代码:
services.Configure<ApiBehaviorOptions>(apiBehaviorOptions => {
apiBehaviorOptions.SuppressModelStateInvalidFilter = true;
});
Run Code Online (Sandbox Code Playgroud)
根据 Simon Vane 的回答,我不得不修改 ASP.Net Core 2.2 的属性,如下所示:
/// <summary>
/// Suppresses the default ApiController behaviour of automatically creating error 400 responses
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class SuppressModelStateInvalidFilterAttribute : Attribute, IActionModelConvention {
private static readonly Type ModelStateInvalidFilterFactory = typeof(ModelStateInvalidFilter).Assembly.GetType("Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilterFactory");
public void Apply(ActionModel action) {
for (var i = 0; i < action.Filters.Count; i++) {
if (action.Filters[i] is ModelStateInvalidFilter || action.Filters[i].GetType() == ModelStateInvalidFilterFactory) {
action.Filters.RemoveAt(i);
break;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我收到了 Microsoft 的回复 - https://github.com/aspnet/Mvc/issues/8575
下面的内容很有魅力。
[AttributeUsage(AttributeTargets.Method)]
public class SuppressModelStateInvalidFilterAttribute : Attribute, IActionModelConvention
{
public void Apply(ActionModel action)
{
for (var i = 0; i < action.Filters.Count; i++)
{
if (action.Filters[i] is ModelStateInvalidFilter)
{
action.Filters.RemoveAt(i);
break;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的控制器中,我可以在重新验证模型之前对其进行更改(请注意 ModelState.Clear()、TryValidateModel 添加到现有模型状态):
if (model == null)
{
return BadRequest(ModelState);
}
model.Property = valueFromPath;
ModelState.Clear();
if (TryValidateModel(model) == false)
{
return BadRequest(ModelState);
}
Run Code Online (Sandbox Code Playgroud)
这可能可以通过针对您的具体情况实现您自己的验证器来解决。文档中对此进行了很好的介绍。
或者是一个自定义模型绑定器,用于创建模型并在验证之前完成所有预处理。
| 归档时间: |
|
| 查看次数: |
1825 次 |
| 最近记录: |