我有一个POST控制器动作,它返回一个局部视图。一切似乎都很容易。但。我使用$.ajax()
加载它,将类型设置为html
。但是当我的模型验证失败时,我认为我应该抛出模型状态错误的错误。但我的回复总是返回500服务器错误。
如何在不返回Json的情况下报告模型状态错误。我仍然希望返回部分视图,我可以直接附加到某个HTML元素。
我还想避免返回错误局部视图。这看起来像是客户端的成功。让客户端解析结果以查看它是否真正成功容易出错。设计人员可能会更改局部视图输出,仅此一项就会破坏功能。所以我想抛出异常,但是将正确的错误消息返回给ajax客户端。
答案 0 :(得分:17)
我必须编写两个独立的部分,自动完全按预期工作。
因此,当控制器操作进程成功时它应该返回一个部分视图,并且当事情不好时它应该抛出一些错误细节,因此客户端的事情将区分成功和失败而不是总是处理成功。
有两个主要部分用于实现此目的:
详细信息然后......
外部链接:我的博客上也提供了所有这些信息(详细说明以及所有代码)。最新的代码更新将始终为published there。
这个课提供两件事
此类稍后在我的自定义错误过滤器中使用。
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;
}
}
}
之后,我只是用我的属性装饰我的控制器动作并瞧。我确实在客户端上遇到了代码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显示垃圾。这就是为什么我设置编码但它不起作用。如果有人为这种特殊性做了解决方法,我会非常乐意收听。
如果我在内容本身返回错误消息,一切都很好。编码是正确的,我可以显示我想要的任何内容。
答案 1 :(得分:3)
试试这个。
public ActionResult DoAjaxAction(Entity entity)
{
if(ModelState.IsValid)
{
return PartialView("Valid_View", entity);
}
else
{
return PartialView("Invalid_View", entity);
}
}