【问题标题】:Model Validation int Required模型验证 int 必需
【发布时间】:2021-08-27 00:29:10
【问题描述】:

我现在正在研究 ASP.NET Core。

我正在构建 Restful API,并编写了以下代码用于模型验证。

public class CreditCard
{
    [Required(ErrorMessage = "Error!")]
    [Range(1, 32, ErrorMessage = "Error")]
    public int Paydate { get; set; }
}

当用户调用 API 时,Paydate 必须有一个数字,但有时它没有。

如果用户调用 API 并像这样抛出数据, {"paydate":""}

会发生这些错误。 'JSON 值无法转换为 System.Int32'

可以在ErrorMessage中显示指定的内容,即使是空字符串吗?

【问题讨论】:

  • 请展示你的控制器实现
  • "Error!" 不是有用的错误消息。为什么不将ErrorMessage 属性留空,以便 ASP.NET 自动生成更有用的错误消息?
  • "Paydate 必须有数字,但有时没有。"所以你的意思是它接受null 或其他类型。如果接受Nullable,则不应应用RequiredAttribute并将Paydate设置为int?类型。错误消息是正确的,因为您的模型预计会收到 int 类型的 Paydate。如果需要接受string,也许你应该修改你的Paydate类型。
  • 使用int?可以防止Null,有时调用API时传值为"",我想显示我在ErrorMessage中设置的消息,而不是自动生成的消息.
  • 在 .Net Framework(使用 Newtonsoft.JSON)中,我将使用 int? Paydate 使其可为空,然后包含 [Required] 属性。但是,.Net Core 默认使用 System.Text.Json。您可以考虑使用这种方法尝试 Newtonsoft.Json,但这是我目前唯一能想到的。

标签: c# asp.net-core


【解决方案1】:

一种方法是您可以删除[ApiController]并在后端判断ModelState:

[HttpPost]
public IActionResult Post(CreditCard model)
{
    if(!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    //do your stuff...
    return Ok(model);
}

另一种方法是继续使用[ApiController] 和自定义ValidationProblemDetails。HTTP 400 响应的默认响应类型是ValidationProblemDetails 类。因此,我们将创建一个继承 ValidationProblemDetails 类的自定义类并定义我们的自定义错误消息:

public class CustomBadRequest : ValidationProblemDetails
{
    public CustomBadRequest(ActionContext context)
    {
        ConstructErrorMessages(context);
        Type = context.HttpContext.TraceIdentifier;
    }

    private void ConstructErrorMessages(ActionContext context)
    {
        foreach (var keyModelStatePair in context.ModelState)
        {
            var key = keyModelStatePair.Key;
            var errors = keyModelStatePair.Value.Errors;
            if (errors != null && errors.Count > 0)
            {
                Errors.Add(key, new[] { "Error!" });
            }
        }
    }
}

注册服务:

services.AddControllers().ConfigureApiBehaviorOptions(options =>
{
    options.InvalidModelStateResponseFactory = context =>
    {
        var problems = new CustomBadRequest(context);

        return new BadRequestObjectResult(problems);
    };
});

【讨论】:

  • 此方法不起作用,因为用户的请求在执行操作之前就显示错误。
  • 第二种方式听起来不错。但是,错误消息会导致我犯模型指定的错误吗?
  • 请测试代码。如果您删除[ApiController],它将到达端点并进入ModelState.IsValid。你问can an error message cause me to make an error designated by the model?,答案是当然可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 2019-01-04
  • 1970-01-01
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
相关资源
最近更新 更多