Подтвердить что ты не робот

Вернуться 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 и соответствующему вызову функции.

Любые мысли о том, что может происходить и как это исправить? Спасибо вам

4b9b3361

Ответ 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);
    }
}

Затем вы можете вернуть это как результат, и код состояния будет установлен в ответ. Вы также можете проверить код состояния на результат в своих тестах.