【问题标题】:How to read validation error message when fail validation logic for passwords密码验证逻辑失败时如何读取验证错误消息
【发布时间】:2020-05-10 09:45:13
【问题描述】:

在我的 IdentityConfig.cs 中

   manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };

在我的 Web MVC UI 中,这是我的操作方法

HttpResponseMessage responsePost = GlobalVariables.WebApiClient.PostAsJsonAsync("Account/Register", registerBindingModel).Result;
        if (responsePost.IsSuccessStatusCode)
        {
                ViewBag.Message = "Added";
        }
        else
        {
            ViewBag.Message = "Internal server Error: " + responsePost.ReasonPhrase;
        }

代码有效。如果它通过密码验证逻辑,我可以发布数据。但如果它失败了,它只会将Internal server Error: Bad Request 退回到我的用户界面。但是当我使用 Postman 对其进行测试时,我可以看到来自身份的错误消息。示例Passwords must have at least one lowercase ('a'-'z').

这个错误信息存储在HttpResponseMessage哪里?

注册API方法

[AllowAnonymous]
    [HttpPost]
    [Route("Register")]
    public async Task<IHttpActionResult> Register(RegisterBindingModel model)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };

        IdentityResult result = await UserManager.CreateAsync(user, model.Password);

        if (!result.Succeeded)
        {
            return GetErrorResult(result);
        }

        return Ok();
    }

private IHttpActionResult GetErrorResult(IdentityResult result)
    {
        if (result == null)
        {
            return InternalServerError();
        }

        if (!result.Succeeded)
        {
            if (result.Errors != null)
            {
                foreach (string error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }
            }

            if (ModelState.IsValid)
            {
                // No ModelState errors are available to send, so just return an empty BadRequest.
                return BadRequest();
            }

            return BadRequest(ModelState);
        }

        return null;
    }

【问题讨论】:

  • HttpResponseMessage 类具有内容属性。您需要读取该属性的值。 stackoverflow.com/questions/29975001/…
  • @ChetanRanpariya 现在我可以使用var content = responsePost.Content.ReadAsStringAsync(); ViewBag.Message = "Error: " + content.Result; 读取错误,但它的输出是Error: {"$id":"1","Message":"The request is invalid.","ModelState":{"$id":"2","":["Passwords must have at least one lowercase ('a'-'z')."]}}。如何只阅读ModelState 错误消息?

标签: c# asp.net-mvc api asp.net-identity


【解决方案1】:

基于 cmets,您需要解析字符串 content,它返回一个 JSON 字符串,假设您的 API 是以这种方式设计的。

我不确定您的 API 代码,但如果您需要发送您的 ModelState,您可以使用以下方式以 JSON 形式发送:

return Json(ModelState);

您不应该使用IsSuccessStatusCode 来检查您的逻辑。基本上,它是一个指示 HTTP 响应是否成功的值。如果 HttpStatusCode 在成功范围 (200-299) 内,则为 true;否则falseIsSuccessStatusCode的算法如下所示:

public bool IsSuccessStatusCode
{
    get { return ((int)statusCode >= 200) && ((int)statusCode <= 299); }
}

可以清楚的看到,上面的函数只依赖于从API接收到的statusCode

因此,您需要根据从 API 收到的 content 定义您的逻辑。根据您在 API 中定义的条件,创建一个模型来保存来自 API 的响应。

HttpResponseMessage responsePost = GlobalVariables.WebApiClient.PostAsJsonAsync("Account/Register", registerBindingModel).Result;
MyAPIResponse model=new MyAPIResponse();
string content=string.Empty;

    if (responsePost.IsSuccessStatusCode)
    {
      content = response.Content.ReadAsStringAsync().Result;
      model = JsonConvert.DeserializeObject<MyAPIResponse>(content); 
      //or if you do not want a model structure for the parsing
      //var parsedmodel = JsonConvert.DeserializeObject<dynamic>(content);                   
    }

    ViewBag.Message=model.message;

我无法解析您评论中发布的内容,因为它不是有效的JSON 字符串。您需要为您的逻辑生成正确的JSON 格式。

编辑:

因此您可以使用扩展方法将 ModelState 错误作为 JSON 发送:

public static class ModelStateHelper
{
    public static IEnumerable Errors(this ModelStateDictionary modelState)
    {
        if (!modelState.IsValid)
        {
            return modelState.ToDictionary(kvp => kvp.Key,
                kvp => kvp.Value.Errors
                                .Select(e => e.ErrorMessage).ToArray())
                                .Where(m => m.Value.Any());
        }
        return null;
    }
}

然后从Controller 操作调用该扩展方法:

if (!ModelState.IsValid)
{
    return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}

【讨论】:

  • 我认为我的错误是 Json 格式。我添加了错误屏幕截图
  • @Steve 是的,您在评论中提到的错误格式是不正确的JSON 字符串。
  • 在原始帖子中添加了额外的代码。错误添加到ModelState.AddModelError
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
相关资源
最近更新 更多