2013-06-26 3 views
13

Von meiner MVC3-Controller-Aktion möchte ich HTTP 403 zurückgeben, "status description" auf eine bestimmte Zeichenfolge setzen und diese Zeichenfolge auch im Ergebnisinhalt zurückgeben, so dass sie im Browser sichtbar ist.Wie gebe ich einen Statuscode, eine Statusbeschreibung und einen Text zusammen in MVC3 zurück?

Ich kann ContentResult zurückgeben, um Inhalt, aber nicht einen Statuscode (wie 403) und nicht eine Statusbeschreibung anzugeben. Ich kann HttpStatusCodeResult verwenden, um einen Statuscode und eine Statusbeschreibung, aber nicht den Ergebnisinhalt anzugeben.

Wie erstelle ich ein Aktionsergebnis, das alle drei enthält?

+1

warum nicht benutzerdefinierte Json ({code: descr:}) Anruf verwenden? – Tigran

+1

@Tigran: IMO für diesen einfachen Zweck, der ein Overkill wäre. – sharptooth

+0

so viel wie mir bewusst ist, ist es nicht möglich, so dass Sie esplicit komponierte Objekt erstellen müssen. In diesem Fall, imo, ist die einfachste Lösung ein benutzerdefiniertes Json-Objekt. Aber ich bin kein ASP.NET-Experte, mag es eine einfachere Lösung dafür geben. – Tigran

Antwort

9

Ist dies nicht zu stark verschmutzt ist

Response.Clear(); 
Response.Write("Some specific string"); 
return new HttpStatusCodeResult(403, "another specific string"); 
+2

oder ähnlich, Response.StatusCode = 403; Response.StatusDescription = "foo"; return Inhalt ("bad request mate"); ' – drch

+2

Vergiss nicht, die Antwort zuerst zu löschen, wenn du vor dem Code damit herumhantierst:' Response.Clear(); ' – Haney

13

Häufig würden Sie dies, indem Sie den Antwortcode dann getan sehen eine regelmäßige Action Rückkehr

public ActionResult Foo() 
{ 
    Response.StatusCode = 403; 
    Response.StatusDescription = "Some custom message"; 

    return View(); // or Content(), Json(), etc 
} 

Wenn Sie das wirklich brauchen eine Action zu sein, du erstellst dein eigenes.

Beispiel:

public class HttpStatusContentResult : ActionResult 
{ 
    private string _content; 
    private HttpStatusCode _statusCode; 
    private string _statusDescription; 

    public HttpStatusContentResult(string content, 
            HttpStatusCode statusCode = HttpStatusCode.OK, 
            string statusDescription = null) 
    { 
     _content = content; 
     _statusCode = statusCode; 
     _statusDescription = statusDescription; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     var response = context.HttpContext.Response; 
     response.StatusCode = (int) _statusCode; 
     if (_statusDescription != null) 
     { 
      response.StatusDescription = _statusDescription; 
     } 

     if (_content != null) 
     { 
      context.HttpContext.Response.Write(_content); 
     } 
    } 
} 
+3

Wenn' _statusDescription' null ist, du könnte es einen Wert von "HttpWorkerRequest.GetStatusDescription (response.StatusCode)" zuweisen, was unter der Haube eine sehr schnelle Suche in 'string [] [] s_HTTPStatusDescriptions' wie 's_HTTPStatusDescriptions [StatusCode/100] [StatusCode% 100]' ist. Der abgerufene Wert ist immer eine kurze Beschreibung des Statuscodes wie "OK" oder "Verboten" oder eine leere Zeichenfolge, wenn keine übereinstimmende Beschreibung gefunden wird. – Triynko

-1

Ich ging verrückt versuchen, diesen Code zu erhalten zu arbeiten, bevor ich erkennen, dass es die GetAwaiter() war OnCompleted (...), dass das Problem ist.. Hier ist die Version, die ich funktionierte:

public class ApiControllerBase : ApiController 
{ 
    ... 
    // Other code 
    ... 

    public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) 
    { 
     return base 
     .ExecuteAsync(controllerContext, cancellationToken) 
     .ContinueWith(t => 
     { 
      t.Result.Headers.CacheControl = new CacheControlHeaderValue() 
      { 
       NoStore = true, 
       NoCache = true, 
       MaxAge = new TimeSpan(0), 
       MustRevalidate = true 
      }; 
      t.Result.Headers.Pragma.Add(new NameValueHeaderValue("no-cache")); 
      t.Result.Content.Headers.Expires = DateTime.Parse("01 Jan 1990 00:00:00 GMT"); 

      return t.Result; 
     }, cancellationToken); 
    } 
} 
Verwandte Themen