모든 ModelState 오류 메시지 목록을 어떻게 얻습니까? 모든 키를 얻기 위해이 코드를 찾았습니다. ( ModelState 오류가있는 키 목록 반환 )
var errorKeys = (from item in ModelState
where item.Value.Errors.Any()
select item.Key).ToList();
그러나 오류 메시지를 IList 또는 IQueryable로 어떻게 얻을 수 있습니까?
나는 갈 수 있었다 :
foreach (var key in errorKeys)
{
string msg = ModelState[error].Errors[0].ErrorMessage;
errorList.Add(msg);
}
그러나 그것은 수동으로하는 것입니다-확실히 LINQ를 사용하는 방법이 있습니까? .ErrorMessage 속성은 지금까지 체인에 있으므로 LINQ를 작성하는 방법을 모르겠습니다 …
답변
당신은 넣을 수 있습니다 아무것도 당신이 내부에 원하는 select
절을 :
var errorList = (from item in ModelState
where item.Value.Errors.Any()
select item.Value.Errors[0].ErrorMessage).ToList();
편집 : 다음 from
과 같은 절 을 추가하여 여러 오류를 별도의 목록 항목으로 추출 할 수 있습니다 .
var errorList = (from item in ModelState.Values
from error in item.Errors
select error.ErrorMessage).ToList();
또는:
var errorList = ModelState.Values.SelectMany(m => m.Errors)
.Select(e => e.ErrorMessage)
.ToList();
2 차 편집 : 당신이 찾고있는 Dictionary<string, string[]>
:
var errorList = ModelState.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
);
답변
다음은 모든 부분을 종합 한 전체 구현입니다.
먼저 확장 메소드를 작성하십시오.
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;
}
}
그런 다음 해당 확장 메소드를 호출하고 컨트롤러 조치 (있는 경우)에서 오류를 json으로 리턴하십시오.
if (!ModelState.IsValid)
{
return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}
마지막으로 클라이언트 측에서 오류를 표시하십시오 (jquery.validation 스타일이지만 다른 스타일로 쉽게 변경할 수 있음)
function DisplayErrors(errors) {
for (var i = 0; i < errors.length; i++) {
$("<label for='" + errors[i].Key + "' class='error'></label>")
.html(errors[i].Value[0]).appendTo($("input#" + errors[i].Key).parent());
}
}
답변
Hashtable
문자열 배열 형태의 속성으로 키와 오류가있는 JSON 객체를 값으로 얻을 수 있도록 여기에서 사용 하고 싶습니다.
var errors = new Hashtable();
foreach (var pair in ModelState)
{
if (pair.Value.Errors.Count > 0)
{
errors[pair.Key] = pair.Value.Errors.Select(error => error.ErrorMessage).ToList();
}
}
return Json(new { success = false, errors });
이렇게하면 다음과 같은 응답을 얻을 수 있습니다.
{
"success":false,
"errors":{
"Phone":[
"The Phone field is required."
]
}
}
답변
이 작업을 수행하는 방법에는 여러 가지가 있습니다. 여기 내가 지금 해요 …
if (ModelState.IsValid)
{
return Json("Success");
}
else
{
return Json(ModelState.Values.SelectMany(x => x.Errors));
}
답변
가장 쉬운 방법 BadRequest
은 ModelState 자체 로 a 를 반환하는 것입니다.
예를 들어 PUT
:
[HttpPut]
public async Task<IHttpActionResult> UpdateAsync(Update update)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// perform the update
return StatusCode(HttpStatusCode.NoContent);
}
Update
클래스 에서 휴대 전화와 같은 데이터 주석을 사용하는 경우 :
public class Update {
[StringLength(22, MinimumLength = 8)]
[RegularExpression(@"^\d{8}$|^00\d{6,20}$|^\+\d{6,20}$")]
public string MobileNumber { get; set; }
}
잘못된 요청에 따라 다음을 반환합니다.
{
"Message": "The request is invalid.",
"ModelState": {
"update.MobileNumber": [
"The field MobileNumber must match the regular expression '^\\d{8}$|^00\\d{6,20}$|^\\+\\d{6,20}$'.",
"The field MobileNumber must be a string with a minimum length of 8 and a maximum length of 22."
]
}
}
답변
@ JK 그것은 많은 도움이되었지만 왜 그렇지 않습니까?
public class ErrorDetail {
public string fieldName = "";
public string[] messageList = null;
}
if (!modelState.IsValid)
{
var errorListAux = (from m in modelState
where m.Value.Errors.Count() > 0
select
new ErrorDetail
{
fieldName = m.Key,
errorList = (from msg in m.Value.Errors
select msg.ErrorMessage).ToArray()
})
.AsEnumerable()
.ToDictionary(v => v.fieldName, v => v);
return errorListAux;
}
답변
System.Web.Http.Results.OkNegotiatedContentResult를 살펴보십시오.
던지는 모든 것을 JSON으로 변환합니다.
그래서 나는 이것을했다
var errorList = ModelState.ToDictionary(kvp => kvp.Key.Replace("model.", ""), kvp => kvp.Value.Errors[0].ErrorMessage);
return Ok(errorList);
결과는 다음과 같습니다.
{
"Email":"The Email field is not a valid e-mail address."
}
각 필드에 대해 둘 이상의 오류가있을 때 발생하는 상황을 아직 확인하지 않았지만 요점은 OkNegoriatedContentResult가 훌륭하다는 것입니다!
@SLaks에서 linq / lambda 아이디어를 얻었습니다.