在ASP .NET MVC3上使用HTML而不是JSON进行IIS响应

时间:2013-05-16 08:13:59

标签: json asp.net-mvc-3 error-handling

受试者是自我解释的。我有开发人员和生产环境。开发者环境是我的localhost机器。我在contolers中有动作方法,当出现错误(出错或逻辑不一致)并返回Json-answer时,将响应状态代码设置为500。我的常用方法如下:

[HttpPost]
public ActionResult DoSomething(int id)
{
    try
    {
         // some useful code
    }
    catch(Exception ex)
    {
         Response.StatusCode = 500;
         Json(new { message = "error" }, JsonBehaviour.AllowGet)
    }
}

在生产环境中的客户端。当发生这样的错误时,ajax.response看起来像一个HTML代码,而不是预期的JSON。

考虑一下:

<div class="content-container">
 <fieldset>
   <h2>500 - Internal server error.</h2>
   <h3>There is a problem with the resource you are looking for, and it cannot be displayed.</h3>
</fieldset>
</div>

过滤器上下文不是一个选项。我认为这是某种IIS或web.config问题。

解: 我们决定在Global.asax中的BeginRequest中添加TrySkipIisCustomErrors,它解决了我们应用程序中每个方法的问题。

3 个答案:

答案 0 :(得分:12)

我猜IIS正在提供一些友好的错误页面。您可以尝试通过在响应上设置TrySkipIisCustomErrors属性来跳过此页面:

catch(Exception ex)
{
     Response.StatusCode = 500;
     Response.TrySkipIisCustomErrors = true;
     return Json(new { message = "error" }, JsonBehaviour.AllowGet)
}

答案 1 :(得分:0)

您的IIS是否已配置为将application/json视为有效的mime-type?您可以在IIS管理器中检查服务器的属性,然后单击“MIME类型”。如果没有json,则单击“New”,为扩展名输入“JSON”,为MIME类型输入“application / json”。

答案 2 :(得分:0)

我通过编写自定义json结果解决了这个问题,该结果使用json.net作为序列化程序。这对于IIS修复来说太过分了,但这意味着它可以重用。

public class JsonNetResult : JsonResult
{
    //public Encoding ContentEncoding { get; set; }
    //public string ContentType { get; set; }
    public object Response { get; set; }
    public HttpStatusCode HttpStatusCode { get; set; }

    public JsonSerializerSettings SerializerSettings { get; set; }
    public Formatting Formatting { get; set; }

    public JsonNetResult(HttpStatusCode httpStatusCode = HttpStatusCode.OK)
    {
        Formatting = Formatting.Indented;
        SerializerSettings = new JsonSerializerSettings { };
        SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        HttpStatusCode = httpStatusCode;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        HttpResponseBase response = context.HttpContext.Response;

        response.TrySkipIisCustomErrors = true;

        response.ContentType = !string.IsNullOrEmpty(ContentType) ? ContentType : "application/json";

        if (ContentEncoding != null)
            response.ContentEncoding = ContentEncoding;

        response.StatusCode = (int) HttpStatusCode;

        if (Response != null)
        {
            JsonTextWriter writer = new JsonTextWriter(response.Output) { Formatting = Formatting };

            JsonSerializer serializer = JsonSerializer.Create(SerializerSettings);
            serializer.Serialize(writer, Response);

            writer.Flush();
        }
    }
}

使用:

            try
            {
                return new JsonNetResult()
                {
                    Response = "response data here"
                };
            }
            catch (Exception ex)
            {
                return new JsonNetResult(HttpStatusCode.InternalServerError)
                {
                    Response = new JsonResponseModel
                    {
                        Messages = new List<string> { ex.Message },
                        Success = false,
                    }
                };
            }