web-dev-qa-db-fra.com

Renvoyer Mvc.JsonResult plus set Response.StatusCode

Projet: ASP MVC 4 fonctionnant sous le framework .net 4.0:

Lors de l'exécution d'une application sous VS 2010 express (ou déployée et exécutée sous IIS 7.5 sur ma machine locale), le résultat (pseudocode) suivant d'une action fonctionne comme prévu

[HttpPost]
public ActionResult PostWord(Model model)
{
   ....
   Response.StatusCode = 400;
   Return new JsonResult { data = new {fieldName = "Word", error = "Not really a Word!" } };

(et j'ai attribué les propriétés ContentType et ContentEncoding de l'objet JsonResult, sans différence de comportement)

Lorsque le déployable est déplacé sur un hôte Web (en utilisant IIS 7), firebug me dit que la réponse est comme prévu (400) mais qu'il n'y a pas de JSON dans la réponse (c'est-à-dire qu'il n'y a pas texte quelconque). Si je supprime la ligne

Response.StatusCode = 400;

de l'action, le JSON est parfaitement formé dans la réponse, mais bien sûr le code d'état de la réponse est 200 (OK), ce qui interfère avec le javascript consommateur et l'appel de fonction approprié.

Avez-vous des réflexions sur ce qui pourrait se passer et comment y remédier? Je vous remercie

37
Brent

J'ai eu exactement le même problème; afin de m'assurer que la bonne réponse n'est pas enterrée dans les commentaires (comme c'était le cas pour moi), je tiens à réitérer le commentaire de @ Sprockincat:

Pour moi au moins, c'était en effet un problème avec IIS Erreurs personnalisées, et peut être résolu avec:

Response.TrySkipIisCustomErrors = true;

@Sprockincat - vous devriez obtenir un crédit pour cela. Je le rends juste plus visible parce que c'est une solution si subtile à un problème qui est assez difficile à diagnostiquer.

52
Robert

J'ai créé une sous-classe de JsonResult qui vous permet de spécifier le 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);
    }
}

Ensuite, vous pouvez renvoyer cela comme résultat et le code d'état sera défini sur la réponse. Vous pouvez également tester le code d'état sur le résultat dans vos tests.

2
Richard Garside