密码验证逻辑失败时如何读取验证错误消息
How to read validation error message when fail validation logic for passwords
在我的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;
}
代码有效。如果它通过密码验证逻辑,我可以 post 数据。但如果它失败了,它只是将 Internal server Error: Bad Request
返回到我的 ui。但是当我使用 Postman 对其进行测试时,我可以看到来自 identity 的错误消息。示例 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;
}
根据评论,您需要解析字符串 content
,其中 returns 是 JSON
字符串,假设您的 API
是以这种方式设计的。
我不确定你的 API
代码,但如果你需要发送你的 ModelState
,你可以使用 JSON 形式发送它:
return Json(ModelState);
您不应该使用 IsSuccessStatusCode
来检查您的逻辑。基本上它是一个指示 HTTP 响应是否成功的值。如果 HttpStatusCode 在成功范围 (200-299) 内,则为 true
;否则 false
。 IsSuccessStatusCode
的算法如下所示:
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);
}
在我的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;
}
代码有效。如果它通过密码验证逻辑,我可以 post 数据。但如果它失败了,它只是将 Internal server Error: Bad Request
返回到我的 ui。但是当我使用 Postman 对其进行测试时,我可以看到来自 identity 的错误消息。示例 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;
}
根据评论,您需要解析字符串 content
,其中 returns 是 JSON
字符串,假设您的 API
是以这种方式设计的。
我不确定你的 API
代码,但如果你需要发送你的 ModelState
,你可以使用 JSON 形式发送它:
return Json(ModelState);
您不应该使用 IsSuccessStatusCode
来检查您的逻辑。基本上它是一个指示 HTTP 响应是否成功的值。如果 HttpStatusCode 在成功范围 (200-299) 内,则为 true
;否则 false
。 IsSuccessStatusCode
的算法如下所示:
public bool IsSuccessStatusCode
{
get { return ((int)statusCode >= 200) && ((int)statusCode <= 299); }
}
可以清楚的看到上面的函数只依赖于从API接收到的statusCode
。
因此,您需要根据从 API 收到的 content
来定义您的逻辑。根据您在 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);
}