c# - 禁用单个 .NET Core API 操作的模型验证
问题描述
我有一个 API 控制器,用于在我正在开发的应用程序上执行自动保存。它使用与视图相同的视图模型,其中包含许多必填字段。如果用户在保存表单时尚未完成表单,则自动保存控制器可能需要保存被认为无效的模型。默认情况下,使用该[ApiController]
属性声明的 .NET Core 控制器将自动强制验证。我知道我可以像这样禁用它Startup.cs
:
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
但这将适用于项目中的所有 API 控制器。是否可以仅对一个控制器或操作禁用此默认验证?到目前为止,我发现的所有内容都指示我使用上面的代码,但这并没有完成我正在寻找的东西。
解决方案
您可以覆盖默认值InvalidModelStateResponseFactory
:
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory =
AllowingServerSideValidationToBeDisabledInvalidModelStateResponseFactoryHelper.InvalidModelStateResponseFactory;
});
下面InvalidModelStateResponseFactory
检查OptionalValidationAttribute
控制器操作,并搜索控制验证启用/禁用的表单/查询参数标志:
// Code taken from https://github.com/dotnet/aspnetcore/blob/5747cb36f2040d12e75c4b5b3f49580ef7aac5fa/src/Mvc/Mvc.Core/src/DependencyInjection/ApiBehaviorOptionsSetup.cs#L23
// and is modified to optionally disable validation for controller action methods decorated with OptionalValidationAttribute
public static class AllowingServerSideValidationToBeDisabledInvalidModelStateResponseFactoryHelper
{
public static Func<ActionContext, IActionResult> InvalidModelStateResponseFactory => actionContext =>
{
var shouldEnableDataValidationarameterName = ((OptionalValidationAttribute)((ControllerActionDescriptor)actionContext.ActionDescriptor)
.MethodInfo.GetCustomAttributes(typeof(OptionalValidationAttribute), true)
.SingleOrDefault())?.ShouldEnableDataValidationParameterName;
var isValidationEnabled = true;
if (shouldEnableDataValidationarameterName != null)
{
var httpContextRequest = actionContext.HttpContext.Request;
var shouldEnableDataValidationValue = httpContextRequest.Form[shouldEnableDataValidationarameterName]
.Union(httpContextRequest.Query[shouldEnableDataValidationarameterName]).FirstOrDefault();
isValidationEnabled = shouldEnableDataValidationValue?.ToLower() == bool.TrueString.ToLower();
}
if (!isValidationEnabled)
{
return null;
}
var problemDetailsFactory = actionContext.HttpContext.RequestServices.GetRequiredService<ProblemDetailsFactory>();
var problemDetails = problemDetailsFactory.CreateValidationProblemDetails(actionContext.HttpContext, actionContext.ModelState);
ObjectResult result;
if (problemDetails.Status == 400)
{
// For compatibility with 2.x, continue producing BadRequestObjectResult instances if the status code is 400.
result = new BadRequestObjectResult(problemDetails);
}
else
{
result = new ObjectResult(problemDetails)
{
StatusCode = problemDetails.Status,
};
}
result.ContentTypes.Add("application/problem+json");
result.ContentTypes.Add("application/problem+xml");
return result;
};
}
OptionalValidationAttribute
:_
[AttributeUsage(AttributeTargets.Method)]
public class OptionalValidationAttribute : Attribute
{
public OptionalValidationAttribute(string shouldEnableDataValidationParameterName)
{
ShouldEnableDataValidationParameterName = shouldEnableDataValidationParameterName;
}
public string ShouldEnableDataValidationParameterName { get; }
}
控制器操作的示例用法:
[HttpPost]
[OptionalValidation(shouldEnableDataValidationParameterName: "shouldEnableDataValidation")]
public async Task<IActionResult> Update(
[FromForm] int id,
[FromForm] string name,
[FromForm] bool shouldEnableDataValidation
)
{
...
}
推荐阅读
- r - 在闪亮的应用程序中更改 validate() 中文本的颜色
- python - 面板数据的具有固定效应的泊松回归
- java - Log4j:为什么在提交给 ExecutorService 的 Callable 中登录时缺少日志条目
- pytorch - torch.distributed.barrier() 是如何工作的
- php - 安装 PHP: bash: ./configure: Permission denied
- android - jquery 下拉菜单和文本框在 ios chrome 浏览器上不起作用
- jpa - JPA:检测实体更改的最佳方法是什么
- scala - 基于输入类型的Scala动态返回类型
- python - Pygame 错误:loot() 接受 2 个位置参数,但给出了 3 个
- r - 在加载包之前将 R 环境恢复到条件