Ответы IIS с HTML вместо JSON на ASP.NET MVC3
Субъект является самоочевидным. У меня есть среда разработки и производства. Разработчик env. это моя локальная машина. У меня есть методы действий в contolers, который устанавливает код состояния ответа на 500, когда что-то ошибается (ошибка произошла или логическое несоответствие) и возвращает Json-answer. Мой общий метод выглядит следующим образом:
[HttpPost]
public ActionResult DoSomething(int id)
{
try
{
// some useful code
}
catch(Exception ex)
{
Response.StatusCode = 500;
Json(new { message = "error" }, JsonBehaviour.AllowGet)
}
}
На стороне клиента в производстве env. когда такая ошибка возникла, 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.
РЕШЕНИЕ:
Мы решили добавить TrySkipIisCustomErrors
в BeginRequest в Global.asax и решить проблемы в каждом методе в нашем приложении.
Ответы
Ответ 1
Я предполагаю, что IIS обслуживает некоторую дружественную страницу ошибок. Вы можете попробовать пропустить эту страницу, установив свойство TrySkipIisCustomErrors
в ответе:
catch(Exception ex)
{
Response.StatusCode = 500;
Response.TrySkipIisCustomErrors = true;
return Json(new { message = "error" }, JsonBehaviour.AllowGet)
}
Ответ 2
Является ли ваш IIS настроенным для обработки application/json
как допустимого mime-type
? Вы можете проверить это в свойствах для сервера в диспетчере IIS и выбрать MIME-типы. Если json не существует, нажмите "Создать", введите "JSON" для расширения и "application/json" для типа MIME.
Ответ 3
Я решил это, написав пользовательский результат 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,
}
};
}