简体   繁体   English

对象列表的流畅验证

[英]Fluent validation on a list of objects

Below is my request model for which I implemented fluent validation.下面是我的请求 model,我为此实施了流畅的验证。

public class Request
{
    public List<Customer> Customers { get; set; }
}

public class Customer 
{
    public int CustNumber { get; set; } //Required field
    public string CustName { get; set; } //Required field
    public string CustAddress { get; set; } //Required field
}

Question: If Customers object has 3 items in it but CustNumber is not passed in for 1 item, is it possible to save remaining 2 items from the list to database?问题:如果客户 object 中有 3 个项目,但没有为 1 个项目传入 CustNumber,是否可以将列表中剩余的 2 个项目保存到数据库中? Response should be a 200 HTTP response of a list containing 3 items with 2 success messages and the 3rd should be an error message for the failed item?响应应该是一个 200 HTTP 列表的响应,其中包含 3 个项目和 2 个成功消息,第三个应该是失败项目的错误消息?

My current fluent validation implementation is below and is rejecting the whole request by returning a 400 BadRequest saying "CustNumber is required".我当前的流畅验证实现如下所示,并通过返回 400 BadRequest 说“需要 CustNumber”来拒绝整个请求。

When(model => model.Customers!= null, () =>
{
  RuleForEach(model => model.Customers).SetValidator(new CustomerValidator());
});

public CustomerValidator() {
    RuleFor(item => item.CustNumber).NotEmpty();
    RuleFor(item => item.CustName).NotEmpty();
    RuleFor(item => item.CustAddress).NotEmpty();
}

Below is an example,下面是一个例子,

Request:要求:

{
"Customers": [
    {
        "CustNumber": 123,
        "CustName": "Test1",
        "CustAddress": "US"
    },
    {
        "CustNumber": 456,
        "CustName": "Test2",
        "CustAddress": "US"
    },
    {
        "CustName": "Test3",
        "CustAddress": "US"
    }
  ]
}

Expected Response:预期响应:

{
"CustResult": [
    {
        "CustNumber": 123,
        "Status": "Success"
    },
    {
        "CustNumber": 456,
        "Status": "Success"
    },
    {
        "Status": "Customers[2].CustNumber is required"
    },
  ]
}

Firstly,if you want CustNumber could be null, you set the property public int? CustNumber { get; set; }首先,如果你想要CustNumber可以是 null,你设置属性public int? CustNumber { get; set; } public int? CustNumber { get; set; }

Then,if you don't except to receive a 400 result,and keep the contrains of the table with required Attribute,you could create a DTO which doen't have required attr on property and map it to your entity然后,如果您除了收到 400 结果之外没有,并保持表的约束与必需的属性,您可以创建一个 DTO,它没有属性所需的属性,map 它到您的实体

in your controller:在您的 controller 中:

The cusresult you need:您需要的结果:

var resultlist = new List<CusResult>();
for (int i= 0; i < request.Customers.Count; i++)
            {
                var num= request.Customers[i].CustNumber;
                var result = new CusResult()
                {
                    CustNumber = num,
                    Statue=num!=null?"success":String.Format("Customers[{0}].CustmorNum is required",i)
                };
                resultlist.Add(result);
            }

Update the items not null:更新不是 null 的项目:

var updatecustomer = _mapper.Map<IEnumerable<Customer>>(request.Customers.Where(x => x.CustNumber != null));

        _context.AddRange(updatecustomer);
        _context.SaveChanges();

It really is up to you how you want to deal with this.这真的取决于你想如何处理这件事。 My personal opinion is that you should treat the HTTP request as atomic and so if the API isn't able to process the request in it's entirety you should return a 400 or 500 status.我个人的意见是,您应该将 HTTP 请求视为原子请求,因此如果 API 无法完整处理请求,您应该返回 400 或 500 状态。

If you control the client you may consider returning a 207 status code which indicates partial success.如果您控制客户端,您可以考虑返回 207 状态代码,表示部分成功。 Although 207 was introduced for webdav specifically, there's nothing to prevent you from using it.尽管 207 是专门为 webdav 引入的,但没有什么可以阻止您使用它。 In the response body you can specify the status of each element.在响应正文中,您可以指定每个元素的状态。 The response could look like响应可能看起来像

HTTP/1.1 207 Multi-Status
Content-Type: application/json

{
  "results": [
    {
        "customer":"Test1",
        "status": 200
    },
    {
        "customer":"Test2",
        "status": 200
    },
    {
        "customer":"Test3",
        "status": 400,
        "description":"CustNumber is required"
    }
  ]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM