【问题标题】:Model Validation using Fluent Validation on WEB API在 WEB API 上使用 Fluent Validation 进行模型验证
【发布时间】:2019-05-16 06:54:31
【问题描述】:

我正在尝试在 Web API 项目中对我的模型使用流畅的验证。我有两个班级名称 OrderHeader 和 Items 。我在 Items 类上的属性名称为OrderQty,它是一个整数,我已经为 OrderQty 应用了一个规则,因为它应该是数字(即 0-9)。每当我收到对 OrderQty 的 JSON 请求作为字母数字(如 1A)时,我无法序列化 JSON,也无法从 Modelstate 上的流利验证中获取错误消息。如何实现这一点有人可以帮助我吗?提前致谢 !!!

我尝试将 OrderQty 转换为 ToString() 并应用了规则,但在序列化 JSON 时无法收到错误消息。

我的模态类:

public class OrderHeader
{
    public string OrderNumber { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Phone { get; set; }
    public string Created { get; set; }
    public List<Items> Items { get; set; }
}

public class Items
{
   public string ItemNumber { get; set; }
   public string Description { get; set; }
   public int OrderQty { get; set; }
   public double Weight { get; set; }
   public double Price { get; set; }
   public string Status { get; set; }
}

流利的验证

public class OrderHeaderValidator : AbstractValidator<OrderHeader>
{

    public OrderHeaderValidator()
    {
        RuleFor(x => x.OrderNumber.Trim()).NotEmpty().WithMessage("OrderNumber : cannot be blank.").Length(1, 6).WithMessage("OrderNumber : cannot be more than 6 characters.").Matches("^[0-9]*$").WithMessage("OrderNumber : must contains only numbers");
        RuleFor(x => x.Items).SetCollectionValidator(new ItemValidator());
    }
}


public class ItemsValidator : AbstractValidator<Items>
{

    public ItemsValidator()
    {
        RuleFor(x => x.OrderQty.ToString()).NotNull().WithMessage("TotalOrderQuantity : cannot be blank").Matches("^[0-9]*$").WithMessage("TotalOrderQuantity : must contains only numbers");
        RuleFor(x => x.Status.ToUpper()).NotEmpty().WithMessage("Status : Provide the Status").Length(0, 1).WithMessage("Status : cannot be more than 1 character").Matches("O").WithMessage("Status : Must be 'O'");

    }

}

序列化并获取错误消息:

 string errors = JsonConvert.SerializeObject(ModelState.Values
                .SelectMany(state => state.Errors)
                .Select(error => error.ErrorMessage));

我希望输出应该是如果来自 JSON 请求的值为 1A,那么它会显示错误消息:

TotalOrderQuantity : 必须只包含数字

【问题讨论】:

    标签: c# .net asp.net-web-api fluentvalidation


    【解决方案1】:

    您不能将1A 反序列化为int OrderQty。请改用string OrderQty 并在验证器中检查.Must(x =&gt; int.TryParse(x.OrderQty, out _))。

    您的 API 具有像 OrderQty must be integer - int OrderQty 这样的规范是可以的。如果有人尝试发送字符串而不是整数 - 您可以捕获反序列化异常并使用 invalid request: ... 之类的消息拒绝请求

    【讨论】:

    • 我用过 RuleFor(x=>x.OrderQty).Must(validateint).WithMessage("Must be integer");我的 validateint 函数就像 public bool validateint(string value) { int number; bool a = int.TryParse(value, out number);返回一个;它的作品很棒!但我如何才能将错误消息显示为模型中项目列表中具有无效 OrderQty 的项目
    • 就像我如何在错误消息中附加 ItemNumber 一样。我在下面尝试了 RuleFor(m => new { m.OrderQty, m.ItemNumber }).Must(x => validateint(x.OrderQty, x.ItemNumber)) .WithMessage(string.Format("A {0}" ,x.ItemNumber));但我没能成功
    • @Vicky 试试这个.WithMessage(x =&gt; $"A{x.ItemNumber}")
    • 我收到编译时错误,例如意外字符“$”和一些错误
    • 我像这样使用 RuleFor(m => new { m.OrderQty, m.ItemNumber }).Must(x => validateint(x.OrderQty, x.ItemNumber)).WithMessage(x = > $"A{x.ItemNumber}");
    猜你喜欢
    • 2011-12-26
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 2023-02-11
    • 2017-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多