ASP.NET MVC如何将ModelState错误转换为json
如何获得所有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();
第二nd编辑 :你正在寻找一个Dictionary<string, string[]>
:
var errorList = ModelState.ToDictionary( kvp => kvp.Key, kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray() );
以下是将所有部分放在一起的完整实施:
首先创build一个扩展方法:
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.Count() > 0); } 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对象,其中的属性作为键和错误作为string数组forms的值。
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)); }
@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; }
ToDictionary是System.Linq中find的Enumerable扩展,打包在System.Web.Extensions dll http://msdn.microsoft.com/en-us/library/system.linq.enumerable.todictionary.aspx中; 。 这是完整的课程对我来说的样子。
using System.Collections; using System.Web.Mvc; using System.Linq; namespace MyNamespace { public static class ModelStateExtensions { 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.Count() > 0); } return null; } } }
看看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的想法
最简单的方法是使用ModelState本身返回一个BadRequest
:
例如在一个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." ] } }
与返回types的差异,而不是返回IEnumerable
public static class ModelStateHelper { public static IEnumerable<KeyValuePair<string, string[]>> 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; } }
为什么不将原始的ModelState
对象返回给客户端,然后使用jQuery读取值。 对我来说,它看起来更简单,并使用通用数据结构(.net的ModelState
)
以Jsonforms返回ModelState
,只需将它传递给Json类的构造函数(与任何对象一起使用)
C#:
return Json(ModelState);
JS:
var message = ""; if (e.response.length > 0) { $.each(e.response, function(i, fieldItem) { $.each(fieldItem.Value.Errors, function(j, errItem) { message += errItem.ErrorMessage; }); message += "\n"; }); alert(message); }
List<ErrorList> Errors = new List<ErrorList>(); //test errors. var modelStateErrors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors); foreach (var x in modelStateErrors) { var errorInfo = new ErrorList() { ErrorMessage = x.ErrorMessage }; Errors.Add(errorInfo); }
如果你使用jsonresult然后返回
return Json(Errors);
或者你可以简单地返回modelStateErrors,我还没有尝试过。 我所做的是将Errors集合分配给我的ViewModel,然后循环它。在这种情况下,我可以通过json返回我的错误。 我有一个类/模型,我想获得源/关键,但我仍然试图弄清楚。
public class ErrorList { public string ErrorMessage; }
- Node.Js + Socket.IO vs SignalR vs C#WebSocket Server
- 发布到Azure网站后,无法加载文件或程序集System.Web.Http.WebHost
- 不同的ASP.NETcaching选项的优点/缺点
- OWIN和Katana,为什么从服务器上分离应用程序?
- 从Visual Studio 2013的应用程序中删除Application Insight
- 最好的方式来获取所有选定的checkbox在jQuery中VALUES
- Asp.Net URL的绝对path
- 如何从urlstring中删除端口号
- 如何在debuggingASP.NET应用程序时在Fiddler中显示本地主机stream量?