我有一个POST控制器操作,可返回部分视图。一切似乎都很简单。但。我使用加载它$.ajax(),将type设置为html。但是,当我的模型验证失败时,我认为我应该抛出一个带有模型状态错误的错误。但是我的答复总是返回500服务器错误。
$.ajax()
html
如何报告回模型状态错误而又不返回Json并返回任何结果。我仍然想返回可以直接附加到某些HTML元素的局部视图。
我也想避免返回错误的局部视图。这在客户端上看起来很成功。让客户解析结果以查看其是否真正成功很容易出错。设计人员可能会更改部分视图的输出,仅此一项就会破坏功能。所以我想抛出一个异常,但是将正确的错误消息返回给ajax客户端。
我必须编写两个独立的部分,它们 可以完全按预期 自动运行。
因此,当控制器动作过程成功时,它应该返回部分视图;当事情不正常时,它应该引发带有一些失败细节的错误,以便客户端的事情可以区分成功和失败,而不是总是处理成功。
有两个主要部分可用于实现此目的:
然后到细节…
外部链接 :所有这些信息(详细说明以及所有代码)也都可以在我的博客上找到。最新的代码更新将始终在那里发布。
本课提供两件事
此类稍后在我的自定义错误过滤器中使用。
public class ModelStateException : Exception { public Dictionary<string, string> Errors { get; private set; } public ModelStateDictionary ModelState { get; private set; } public override string Message { get { if (this.Errors.Count > 0) { return this.Errors.First().Value; } return null; } } private ModelStateException() { this.Errors = new Dictionary<string, string>(); } public ModelStateException(ModelStateDictionary modelState) : this() { this.ModelState = modelState; if (!modelState.IsValid) { foreach (KeyValuePair<string, ModelState> state in modelState) { if (state.Value.Errors.Count > 0) { this.Errors.Add(state.Key, state.Value.Errors[0].ErrorMessage); } } } } }
当存在任何模型状态错误时,此属性有助于根据HTTP错误代码将错误返回给客户端。
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public class HandleModelStateExceptionAttribute : FilterAttribute, IExceptionFilter { public void OnException(ExceptionContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } if (filterContext.Exception != null && typeof(ModelStateException).IsInstanceOfType(filterContext.Exception) && !filterContext.ExceptionHandled) { filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.ContentEncoding = Encoding.UTF8; filterContext.HttpContext.Response.HeaderEncoding = Encoding.UTF8; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; filterContext.HttpContext.Response.StatusCode = 400; filterContext.HttpContext.Response.StatusDescription = (filterContext.Exception as ModelStateException).Message; } } }
之后,我只需用我的属性和voila装饰我的控制器动作。我确实在客户端上得到了错误,代码为400,并且更正了我在过滤器中设置的信息。然后将该信息显示给用户(当与模型状态错误相关时,它会显示用户应修改哪些表单字段以使表单有效的信息)。
[HandleModelStateException] public ActionResult AddComment(MyModel data) { // check if state is valid if (!this.ModelState.IsValid) { throw new ModelStateException(this.ModelState); } // get data from store return PartialView("Comment", /* store data */ ); }
这使我的代码可以在任何模型状态错误下重复使用,并且这些错误将按原样发送给客户端。
但是仍然存在与此代码相关的一个问题。 当我设置了错误操作过滤器,StatusDescription并且该字符串包含某些特殊字符(如Č)时,客户端上就会出现垃圾。除非我使用IE(我使用的是版本8)。FF和CH显示为垃圾。这就是为什么我设置编码但是不起作用。如果有人对此有特殊的解决方法,我将非常乐意听。 如果我在内容本身中返回错误消息,一切都很好。编码正确,我可以显示任何内容。
StatusDescription