2012-09-25 13 views
8

Jeśli żądany zasób nie zostanie znaleziony przez warstwę usługi zwracającą wartość null do kontrolera Web API; jaki jest najlepszy sposób na przesłanie odpowiedzi do klienta bez twardego kodowania jej w kontrolerze i sprawdzanie, czy jest ona zerowa?ASP.NET Web API i kod stanu dla zerowej odpowiedzi

+0

Można też zwrócić komunikat odpowiedzi o statusie NOTFOUND wewnątrz metody działania kontroler; lub możesz po prostu wyrzucić wyjątek i mieć globalny filtr odwzorowujący typ wyjątku na odpowiednią odpowiedź. Nie jestem pewien, dlaczego sprawdzanie wartości zerowej byłoby problemem, logika działania kontrolera musi obsługiwać różne warunki i mapować je do odpowiedzi z odpowiednim kodem statusu. – Oppositional

+0

Mam filtr globalny, tak jak powiedziałeś. Nie chcę mieć tych zerowych sprawdzeń w każdej akcji kontrolera. –

Odpowiedz

15

Osobiście po prostu wykonuję kontrole w kontrolerach zgodnie z komentarzem Oppozycyjnym, ale to, o co prosisz, jest całkowicie uzasadnione. Ponownie za pomocą filtrów działania albo przymocowane na kontroler (lub zarejestrowanym globalnie) można zrobić coś wzdłuż tych linii:

Przykład Model:

public class Foo 
{ 
    public string Bar { get; set; } 
} 

Przykład Kontroler:

public class FoosController : ApiController 
{ 
    [NullObjectActionFilter] 
    public Foo Get(string id) 
    { 
     // - Returns model and 200 
     //return new Foo() { Bar = "TEST" }; 

     // - Returns 404 
     //return null; 
    } 
} 

Filtr:

public class NullObjectActionFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
    { 
     object outValue = null; 
     actionExecutedContext.Response.TryGetContentValue<object>(out outValue); 
     if (outValue == null) 
     { 
      throw new HttpResponseException(HttpStatusCode.NotFound); 
     } 

     base.OnActionExecuted(actionExecutedContext); 

    } 
} 
11

Zgadzam się z Markiem, że ActionFilter jest drogą do zrobienia - Małe metody działania są dobrym zapachem.

Jednak HttpActionExecutedContext.Response może być null kiedy wystąpi wyjątek; a klasa NullObjectActionFilter pokazana powyżej może ukrywać kody stanu błędów HTTP. Lepiej sprawdź, czy udało się zakończyć pomyślnie i udany kod HTTP.

Oto filtr działanie używam:

/// <summary> 
/// Converts <c>null</c> return values into an HTTP 404 return code. 
/// </summary> 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 
public sealed class NullResponseIs404Attribute : ActionFilterAttribute 
{ 

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
    { 
     if ((actionExecutedContext.Response != null) && actionExecutedContext.Response.IsSuccessStatusCode) 
     { 
      object contentValue = null; 
      actionExecutedContext.Response.TryGetContentValue<object>(out contentValue); 
      if (contentValue == null) 
      { 
       actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, "Object not found"); 
      } 
     } 
    } 

}