【发布时间】:2018-05-02 16:47:50
【问题描述】:
我正在开发一个可供客户使用的 ASP.NET Core 2.0 API。我遇到的一个问题是,当我使用 ModelState 对请求有效负载进行输入验证时,消费者看到的结果错误消息在响应 JSON 中有一个 [objectPrefix].PropertyName。我们的 API 文档列出了属性名称,但没有列出对象类,因此当消费者编写将 JSON 响应反序列化到其本地对象模型的代码时,前缀会产生问题。
我可以在 Startup.cs ConfigureServices 方法中为 Service.AddMvc 或类似的设置任何选项来禁用此前缀吗?
如果重要的话,我在我的 API、.NET Core 2.0.4 和 VS2016 v15.5.7 中使用 Microsoft.AspNetCore.All(2.0.7) 依赖项。
我正在使用 System.ComponentModel.DataAnnotations 库中的数据注释并装饰我创建的 DTO 类属性,如下所示;
[Required]
[MaxLength(14)]
public string AccountNumber
{
get => _accountNumber;
set => _accountNumber = !string.IsNullOrWhiteSpace(value) ? value.Trim() : string.Empty;
}
当消费者在请求载荷中没有提供账号时,返回的错误是这样的;
{
"[AccountDto].AccountNumber": [
"The AccountNumber field is required."
]
}
我想要做的是消除 [AccountDto]。前缀,以便错误 JSON 看起来像这样;
{
"AccountNumber": [
"The AccountNumber field is required."
]
}
我发现了这个SO 帖子,但它似乎引用了旧的 ASP.NET。
目前,我正在让我的客户对 json 响应进行字符串替换,但我真的很想有一个更好的解决方案。
有什么想法吗?
2018 年 5 月 16 日更新
似乎前缀的问题与我在 *ForCreationDtos 中使用 Validate 方法有关。
例如,
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (CompanyId == 0)
{
yield return new ValidationResult("A Company ID is required.", new[] { "CompanyId" });
}
}
但是,我找到了一种解决方法,方法是使用全局 ModelState 处理程序并对其进行修改以解析出前缀。
public class ValidateModelAttribute : ActionFilterAttribute
{
/// <summary>
/// Validates model state upon action execution
/// </summary>
/// <param name="context">ActionExecutingContext object</param>
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.ModelState.IsValid) return;
var errorList = context.ModelState.Where(ms => ms.Value.Errors.Any()).ToDictionary(
kvp => kvp.Key.Replace("[0].", ""),
kvp => kvp.Value.Errors.Select(e => string.IsNullOrEmpty(e.ErrorMessage) ? e.Exception.Message : e.ErrorMessage).ToArray()
);
var globalErrorDto = new GlobalErrorDto { Errors = errorList };
context.Result = new BadRequestObjectResult(globalErrorDto);
}
}
这有点粗略,假设为“[0]”。作为前缀,但这是我在 DTO 类中实现 Validate 方法时得到的前缀。这似乎解决了我的具体问题。
【问题讨论】:
标签: c# .net-core asp.net-core-2.0 modelstate asp.net-core-mvc-2.0