2013-07-07 12 views
22

Moje oprogramowanie pośrednie OWIN wygląda następująco. (Framework to ASP.NET Web API).Zmiana obiektu odpowiedzi z oprogramowania pośredniego OWIN

public class MyMiddleware : OwinMiddleware 
{ 
    public MyMiddleware(OwinMiddleware next) : base(next) { } 

    public override async Task Invoke(OwinRequest request, OwinResponse response) 
    { 
     var header = request.GetHeader("X-Whatever-Header"); 

     await Next.Invoke(request, response); 

     response.SetHeader("X-MyResponse-Header", "Some Value"); 
     response.StatusCode = 403; 

    } 
} 

Pytania:

  1. Czy to zalecana praktyka czerpać z OwinMiddleware? Widzę, że w źródle Katany niektóre klasy oprogramowania pośredniego pochodzą z OwinMiddleware, a niektóre nie.

  2. Widzę, że nagłówki zapytań są w porządku. Ustawienie nagłówka odpowiedzi lub kodu statusu po Next.Invoke w moim oprogramowaniu pośredniczącym nie ma wpływu na odpowiedź zwróconą do klienta. Ale jeśli ustawię nagłówek odpowiedzi lub status przed wywołaniem Next.Invoke, odpowiedź z nagłówkami i ustawionym przeze mnie stanem jest zwracana do klienta. Jaki jest właściwy sposób ich ustawiania?

Odpowiedz

25
  1. Tak, zaleca się pochodzący z OwinMiddleware. Powodem, dla którego niektóre klasy oprogramowania pośredniego nie pochodzą od OwinMiddleware, jest to, że nie zostały jeszcze przełączone, ponieważ klasa została niedawno wprowadzona. Lub, aby z jakiegoś powodu uniknąć sytuacji, w której zestaw będzie zależny od zestawu Microsoft.Owin.

  2. Prawdopodobny powód dla ustawienia odpowiedzi po wywołaniu funkcji Wywołaj dalej nie działa, ponieważ nagłówek HTTP odpowiedzi zostanie wysłany, gdy tylko ktoś rozpocznie zapisywanie w strumieniu treści odpowiedzi. Tak więc wszelkie zmiany w kodzie statusu lub nagłówkach HTTP po zapisaniu komponentu oprogramowania pośredniego w treści odpowiedzi nie będą miały żadnego wpływu.

Możesz spróbować użyć wywołania zwrotnego OnSendingHeaders, które zapewnia OWIN. Oto, jak możesz z niego korzystać:

public override async Task Invoke(IOwinContext context) 
{ 
    var response = context.Response; 
    var request = context.Request; 

    response.OnSendingHeaders(state => 
    { 
     var resp = (OwinResponse)state; 
     resp.Headers.Add("X-MyResponse-Header", "Some Value"); 
     resp.StatusCode = 403; 
     resp.ReasonPhrase = "Forbidden"; 
    }, response); 

    var header = request.Headers["X-Whatever-Header"]; 

    await Next.Invoke(context); 
} 

Kredyt na ciastka314 za aktualizację mojej odpowiedzi.

+0

Dzięki Youssef. W przypadku punktu 2, czy istnieje przykładowy kod w źródle Katany, czy gdzie indziej, na który mogę patrzeć, z punktu widzenia najlepszych praktyk? Wierzę, że to, o co pytam, jest dość powszechną potrzebą i czy każdy powinien to przełączać, aby ustawić nagłówek odpowiedzi, jeśli używamy oprogramowania pośredniego OWIN? Wszelkie wskazówki zostaną docenione. – Badri

+0

Jestem w stanie rozwiązać problem, wykonując sugestię, ale czy nie ma łatwego wyjścia? Mam na myśli to, że to zbyt dużo pracy, aby ustawić nagłówek odpowiedzi na wyjście, szczególnie jeśli jest się przyzwyczajonym do obsługi komunikatów Web API. – Badri

+3

Zaktualizowano odpowiedź za pomocą prostszej metody. Daj mi znać, jeśli to działa. –

7

Próbowałem edytować doskonałą odpowiedź Youssefa, aby poprawić drobny błąd i zaktualizować przykład z tym, jak działa OwinMiddleware.

Edycja została odrzucona (dobrze, zatwierdzona przez jednego, odrzucona przez jedną z nich za zbyt małą i odrzucona przez dwóch za zbyt dużą).

Oto ta wersja kodu Youssef za:

public override async Task Invoke(IOwinContext context) 
{ 
    var response = context.Response; 
    var request = context.Request; 

    response.OnSendingHeaders(state => 
    { 
     var resp = (OwinResponse)state; 
     resp.Headers.Add("X-MyResponse-Header", "Some Value"); 
     resp.StatusCode = 403; 
     resp.ReasonPhrase = "Forbidden"; // if you're going to change the status code 
             // you probably should also change the reason phrase 
    }, response); 

    var header = request.Headers["X-Whatever-Header"]; 

    await Next.Invoke(context); 
} 
+0

nowa OWIN działa tylko z tym nadpisaniem – Raffaeu