ASP.NET MVC3上使用HTML而不是JSON的IIS响应
这个主题是不言自明的。我对开发人员和生产环境进行了测试。开发者环境。是我的本地主机。我在contolers中有一些操作方法,当出现错误(错误发生或逻辑不一致)时,将响应状态代码设置为500,并返回Json应答。我的常用方法如下所示:ASP.NET MVC3上使用HTML而不是JSON的IIS响应,json,asp.net-mvc-3,error-handling,Json,Asp.net Mvc 3,Error Handling,这个主题是不言自明的。我对开发人员和生产环境进行了测试。开发者环境。是我的本地主机。我在contolers中有一些操作方法,当出现错误(错误发生或逻辑不一致)时,将响应状态代码设置为500,并返回Json应答。我的常用方法如下所示: [HttpPost] public ActionResult DoSomething(int id) { try { // some useful code } catch(Exception ex) {
[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>
500-内部服务器错误。
您正在查找的资源有问题,无法显示。
筛选上下文不是一个选项。我认为这是某种IIS或web.config问题
解决方案:
我们决定在Global.asax的BeginRequest中添加
TrySkipIisCustomErrors
,它解决了我们应用程序中每个方法的问题。您的IIS是否配置为将应用程序/json
视为有效的mime类型?您可以在IIS管理器中检查服务器的属性,然后单击MIME类型。如果没有json,请单击“新建”,输入“json”作为扩展,输入“application/json”作为MIME类型。我猜IIS提供了一些友好的错误页面。您可以通过在响应上设置tryskipiiscustomerors
属性来尝试跳过此页面:
catch(Exception ex)
{
Response.StatusCode = 500;
Response.TrySkipIisCustomErrors = true;
return Json(new { message = "error" }, JsonBehaviour.AllowGet)
}
我通过编写一个自定义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();
}
}
}
使用:
试试看
{
返回新的JsonNetResult()
{
Response=“此处的响应数据”
};
}
捕获(例外情况除外)
{
返回新的JsonNetResult(HttpStatusCode.InternalServerError)
{
Response=newjsonresponsemodel
{
Messages=新列表{ex.Message},
成功=错误,
}
};
}
在调用Json
函数之前是否有return
?@Zoka,是的,corse return仍然在那里。谢谢。没有:(这种类型实际上没有在我的iis上注册。我添加了它,但没有做任何更改。@Khanh To,试图跳过iis错误似乎是一种黑客行为。不,一点也没有。它不是黑客行为。友好的错误页是ASP.NET中内置的功能。如果你不喜欢它们,就不要使用它们。但是如果你决定使用它们,你应该知道后果。)nces(您不能通过自定义响应设置错误状态代码)而不明确告知IIS。我认为这是一个很好的解决方案,但似乎仍然是IIS的问题。我们决定将TrySkipIisCustomErrors
添加到BeginRequest in Global.asax中,并解决了应用程序中每个方法的问题。谢谢。
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,
}
};
}