jquery – 如何处理返回PartialView的ajax调用的控制器操作中的模型状态错误

我有一个POST控制器操作返回部分视图。一切似乎都很简单。但。我使用$ .ajax()加载它,设置类型为html。但是当我的模型验证失败时,我以为我应该抛出模型状态错误错误。但我的回复总是返回500服务器错误

如何返回模型状态错误,而不返回任何结果的Json。我仍然希望返回部分视图,我可以直接附加到一些HTML元素。

编辑

我也想避免返回错误部分视图。这将在客户端看起来像一个成功。让客户端解析结果,看看它是否实际的成功容易出错。设计师可能会更改部分视图输出,这将单独破坏功能。所以我想抛出一个异常,但是正确的错误消息返回给ajax客户端。

解决方法

我必须编写两个独立的部分,这些部分自动按照意图进行工作。

因此,当控制器操作过程成功时,它应该返回部分视图,并且当事情不正确时,它会抛出一些错误,因为客户端上的某些事情会区分成功以及失败,而不是总是处理成功。

有两个主要部分用于实现这一点:

>一个自定义异常类,当出现错误时抛出异常,所以我们可以区分出现任何时候出现的任何原因和与处理有关的错误的异常(最引人注目的是无效的模型状态)
>异常行为过滤器捕获我们的自定义异常并根据该异常准备结果;从代码中可以看出,我们的自定义异常将保存有关模型状态错误的信息,因此此过滤器将能够返回自定义HTTP状态代码以及一些文本信息

关于细节,那么…

External link: All this information (detailed explanation as well as all the code) is also available on my blog. Latest code updates will always be 07000.

自定义异常类

这个班提供两件事

>使模型状态错误与常规异常区分开来很简单
>提供一些我以后可以使用的基本功能

此类以后在我的自定义错误过滤器中使用。

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显示垃圾。这就是为什么我设置编码,但它不工作。如果有人有这个特殊性的解决方法,我会很乐意听。如果我在内容本身返回错误信息,一切都很好。编码是正确的,我可以显示任何我想要的。

相关文章

jQuery插件的种类 1、封装对象方法 这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进...
扩展jQuery插件和方法的作用是非常强大的,它可以节省大量开发时间。 入门 编写一个jQuery插件开始于给...
最近项目中需要实现3D图片层叠旋转木马切换的效果,于是用到了jquery.roundabout.js。 兼容性如图: ht...
一、什么是deferred对象? 开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异...
AMD 模块 AMD(异步模块定义,Asynchronous Module Definition)格式总体的目标是为现在的开发者提供一...