Вернуться Mvc.JsonResult плюс установить Response.StatusCode
Проект: ASP MVC 4 работает под .NET Framework:
При запуске приложения под VS 2010 Express (или развернутого и работающего под IIS 7.5 на моем локальном компьютере) следующее (псевдокод) результат действия работает как ожидалось
[HttpPost]
public ActionResult PostWord(Model model)
{
....
Response.StatusCode = 400;
Return new JsonResult { data = new {fieldName = "Word", error = "Not really a word!" } };
(и я присвоил свойства ContentType и ContentEncoding объекта JsonResult без разницы в поведении)
Когда развертывание перемещается на веб-хост (с использованием IIS 7), firebug сообщает мне, что ответ такой, как ожидалось (400), но в ответе нет JSON (т.е. текста нет). Если я удалю строку
Response.StatusCode = 400;
от действия, JSON отлично формируется в ответе, но, конечно, код состояния ответа 200 (OK), который мешает потребляющему javascript и соответствующему вызову функции.
Любые мысли о том, что может происходить и как это исправить? Спасибо вам
Ответы
Ответ 1
У меня была такая же проблема; чтобы убедиться, что правильный ответ не похоронили в комментариях (как это было для меня), я хочу повторить комментарий @Sprockincat:
Для меня, по крайней мере, это действительно проблема с ошибками IIS Custom и может быть решена с помощью:
Response.TrySkipIisCustomErrors = true;
@Sprockincat - вы должны получить кредит на это. Я просто делаю его более заметным, потому что это такое тонкое решение проблемы, которую довольно сложно диагностировать.
Ответ 2
Я создал подкласс JsonResult, который позволяет вам указать HttpStatusCode.
public class JsonResultWithHttpStatusCode : JsonResult
{
private int _statusCode;
private string _statusDescription;
public JsonResultWithHttpStatusCode(object data, HttpStatusCode status)
{
var code = Convert.ToInt32(status);
var description = HttpWorkerRequest.GetStatusDescription(code);
Init(data, code, description);
}
public JsonResultWithHttpStatusCode(object data, int code, string description)
{
Init(data, code, description);
}
private void Init(object data, int code, string description)
{
Data = data;
_statusCode = code;
_statusDescription = description;
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.StatusCode = _statusCode;
context.HttpContext.Response.StatusDescription = _statusDescription;
base.ExecuteResult(context);
}
}
Затем вы можете вернуть это как результат, и код состояния будет установлен в ответ. Вы также можете проверить код состояния на результат в своих тестах.