키 값을 몰라도 modelState에서 모든 오류 메시지를 가져오고 싶습니다. ModelState에 포함 된 모든 오류 메시지를 가져 오기 위해 반복합니다.
어떻게해야합니까?
foreach (var error in ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors)) { DoSomething(error); }
키 값을 몰라도 modelState에서 모든 오류 메시지를 가져오고 싶습니다. ModelState에 포함 된 모든 오류 메시지를 가져 오기 위해 반복합니다.
어떻게해야합니까?
foreach (var error in ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors)) { DoSomething(error); }
답변:
foreach (ModelState modelState in ViewData.ModelState.Values) {
foreach (ModelError error in modelState.Errors) {
DoSomethingWith(error);
}
}
ASP.NET MVC에서 모델 상태 오류 모음을 얻는 방법을 참조하십시오 . .
Value.ErrorMessage
있고 대신에Value.Exception.Message
foreach (KeyValuePair<string, ModelState> kvp in htmlHelper.ViewData.ModelState) {
이 줄을 그 아래에 삽입하십시오 var modelState = kvp.Value;
. 키를 얻을 수 있습니다kvp.Key
LINQ 사용 :
IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);
List<string> errors = new List<string>()
대신 하는 var errors = new List<string>()
것은 시간 낭비이지만 IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);
반환 유형이 실제로 명확하지 않은 글쓰기 는 가독성 측면에서 실제로 더 큽니다. (비주얼 스튜디오 마우스를 가져가 당신에게 줄 수있는 경우에도)
모든 오류 메시지를 하나의 문자열로 결합하려는 경우 LINQ 버전을 기반으로합니다.
string messages = string.Join("; ", ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => x.ErrorMessage));
약간의 LINQ를 사용하여이 작업을 수행 할 수있었습니다.
public static List<string> GetErrorListFromModelState
(ModelStateDictionary modelState)
{
var query = from state in modelState.Values
from error in state.Errors
select error.ErrorMessage;
var errorList = query.ToList();
return errorList;
}
위의 메서드는 유효성 검사 오류 목록을 반환합니다.
추가 자료 :
디버깅하는 동안 모든 ModelState 오류를 표시하기 위해 각 페이지의 맨 아래에 테이블을 배치하는 것이 유용하다는 것을 알았습니다.
<table class="model-state">
@foreach (var item in ViewContext.ViewData.ModelState)
{
if (item.Value.Errors.Any())
{
<tr>
<td><b>@item.Key</b></td>
<td>@((item.Value == null || item.Value.Value == null) ? "<null>" : item.Value.Value.RawValue)</td>
<td>@(string.Join("; ", item.Value.Errors.Select(x => x.ErrorMessage)))</td>
</tr>
}
}
</table>
<style>
table.model-state
{
border-color: #600;
border-width: 0 0 1px 1px;
border-style: solid;
border-collapse: collapse;
font-size: .8em;
font-family: arial;
}
table.model-state td
{
border-color: #600;
border-width: 1px 1px 0 0;
border-style: solid;
margin: 0;
padding: .25em .75em;
background-color: #FFC;
}
</style>
지금까지 주어진 답변에서 조언을 따랐다는 것을 알았으므로 오류 메시지를 설정하지 않고 예외가 발생하여 ErrorMessage와 Exception을 얻는 데 실제로 필요한 모든 문제를 잡을 수 있습니다.
String messages = String.Join(Environment.NewLine, ModelState.Values.SelectMany(v => v.Errors)
.Select( v => v.ErrorMessage + " " + v.Exception));
또는 확장 방법으로
public static IEnumerable<String> GetErrors(this ModelStateDictionary modelState)
{
return modelState.Values.SelectMany(v => v.Errors)
.Select( v => v.ErrorMessage + " " + v.Exception).ToList();
}
누구나 오류 메시지를 강력한 형식의보기로 바인딩하기 위해 Model 속성 이름을 반환하려는 경우.
List<ErrorResult> Errors = new List<ErrorResult>();
foreach (KeyValuePair<string, ModelState> modelStateDD in ViewData.ModelState)
{
string key = modelStateDD.Key;
ModelState modelState = modelStateDD.Value;
foreach (ModelError error in modelState.Errors)
{
ErrorResult er = new ErrorResult();
er.ErrorMessage = error.ErrorMessage;
er.Field = key;
Errors.Add(er);
}
}
이렇게하면 실제로 오류를 던진 필드와 오류를 묶을 수 있습니다.
오류 메시지 자체를 출력하는 것만으로는 충분하지 않았지만 이것은 트릭을 수행했습니다.
var modelQuery = (from kvp in ModelState
let field = kvp.Key
let state = kvp.Value
where state.Errors.Count > 0
let val = state.Value?.AttemptedValue ?? "[NULL]"
let errors = string.Join(";", state.Errors.Select(err => err.ErrorMessage))
select string.Format("{0}:[{1}] (ERRORS: {2})", field, val, errors));
Trace.WriteLine(string.Join(Environment.NewLine, modelQuery));
누군가가 필요로하는 경우를 위해 프로젝트에서 다음 정적 클래스를 만들고 사용합니다.
사용 예 :
if (!ModelState.IsValid)
{
var errors = ModelState.GetModelErrors();
return Json(new { errors });
}
사용 :
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using WebGrease.Css.Extensions;
수업:
public static class ModelStateErrorHandler
{
/// <summary>
/// Returns a Key/Value pair with all the errors in the model
/// according to the data annotation properties.
/// </summary>
/// <param name="errDictionary"></param>
/// <returns>
/// Key: Name of the property
/// Value: The error message returned from data annotation
/// </returns>
public static Dictionary<string, string> GetModelErrors(this ModelStateDictionary errDictionary)
{
var errors = new Dictionary<string, string>();
errDictionary.Where(k => k.Value.Errors.Count > 0).ForEach(i =>
{
var er = string.Join(", ", i.Value.Errors.Select(e => e.ErrorMessage).ToArray());
errors.Add(i.Key, er);
});
return errors;
}
public static string StringifyModelErrors(this ModelStateDictionary errDictionary)
{
var errorsBuilder = new StringBuilder();
var errors = errDictionary.GetModelErrors();
errors.ForEach(key => errorsBuilder.AppendFormat("{0}: {1} -", key.Key,key.Value));
return errorsBuilder.ToString();
}
}
그리고 이것은 작동합니다 :
var query = from state in ModelState.Values
from error in state.Errors
select error.ErrorMessage;
var errors = query.ToArray(); // ToList() and so on...
SelectMany
가능할 때 사용할 점 은 없습니다.
이것은 @Dunc의 대답에 따라 확장됩니다. xml 문서 주석 참조
// ReSharper disable CheckNamespace
using System.Linq;
using System.Web.Mvc;
public static class Debugg
{
/// <summary>
/// This class is for debugging ModelState errors either in the quick watch
/// window or the immediate window.
/// When the model state contains dozens and dozens of properties,
/// it is impossible to inspect why a model state is invalid.
/// This method will pull up the errors
/// </summary>
/// <param name="modelState">modelState</param>
/// <returns></returns>
public static ModelError[] It(ModelStateDictionary modelState)
{
var errors = modelState.Values.SelectMany(x => x.Errors).ToArray();
return errors;
}
}
<div class="text-danger" style="direction:rtl" asp-validation-summary="All"></div>
간단히 asp-validation-summary Tag Helper를 사용하십시오.
@Html.ValidationSummary()
를 표시하는 경우 모든 오류를 면도기에 빠르게 표시 할 수 있습니다.