如何反序列化422无法处理的实体错误模型并将错误绑定到asp.net核心剃须刀页面模型状态

问题描述 投票:1回答:1

我的Asp.Net Core 3.1 API返回如下所示的422 Unprocessable Entity错误响应:

{
  "type": "https://test.com/modelvalidationproblem",
  "title": "One or more model validation errors occurred.",
  "status": 422,
  "detail": "See the errors property for details.",
  "instance": "/api/path",
  "traceId": "8000003f-0001-ec00-b63f-84710c7967bb",
  "errors": {
    "FirstName": [
      "The FirstName field is required."
    ]
  }
}

如何反序列化此响应并将错误添加到Asp.Net Core 3.1 Razor Pages中的模型验证错误?

我试图创建模型,如下所示,

错误模型:

public class UnprocessableEntity
{
    public string Type { get; set; }
    public string Title { get; set; }
    public int Status { get; set; }
    public string Detail { get; set; }
    public string Instance { get; set; }
    public string TraceId { get; set; }
    public Errors Errors { get; set; }
}

public class Errors
{
    ....// what should I need to add here? Keys and messages will be dynamic
}

但是我应该在Errors类中添加什么?错误键和消息将是动态的。

一旦知道了以上几点,就可以在剃刀页面中添加模型状态错误,如下所示,

using var responseStream = await response.Content.ReadAsStreamAsync();
var errorResponse = await JsonSerializer.DeserializeAsync<UnprocessableEntity>(responseStream);

foreach (var error in errorResponse.errors)
{
    ModelState.AddModelError(error.key, error.Message[0]); // I'm stuck here
}
asp.net-core-webapi razor-pages asp.net-core-3.1 modelstate http-status-code-422
1个回答
0
投票

首先,您应确保键字段名称与从api(pay attention to case)返回的json相同。

 public class UnprocessableEntity
{
    public string type { get; set; }
    public string tTitle { get; set; }
    public int status { get; set; }
    public string detail { get; set; }
    public string instance { get; set; }
    public string traceId { get; set; }
    public Errors errors { get; set; }
}

然后,Errors类的字段应包含已验证类的所有字段,并且字段名称应一致,但是您需要使用define their type as an array to receive,因为json中的错误返回的每个字段都是一个数组。 (在这里,我创建了一个简单的名为StudInfo的经过验证的类):

    public class StudInfo
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
    }


    public class Errors
    {
        public List<string> Id { get; set; }
        public List<string> Name { get; set; }
    }

然后您可以按以下方式使用代码:

       using var responseStream = await response.Content.ReadAsStreamAsync();
       var errorResponse = await JsonSerializer.DeserializeAsync<UnprocessableEntity>(responseStream);
        var t = typeof(Errors);
        var fieldNames = typeof(Errors).GetProperties()
                        .Select(field => field.Name)
                        .ToList();
        foreach (var name in fieldNames)
        {
            List<string> errorLists = (List<string>)errorResponse.errors.GetType().GetProperty(name).GetValue(errorResponse.errors);
            if (errorLists != null)
            {
                ModelState.AddModelError(name, errorLists[0]); 
            }

        }
© www.soinside.com 2019 - 2024. All rights reserved.