2013-07-07 3 views
22

Мое промежуточное ПО OWIN - это так. (Framework - это веб-интерфейс ASP.NET).Изменение объекта ответа от промежуточного программного обеспечения 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; 

    } 
} 

Вопросы:

  1. ли рекомендуемая практика извлечь из OwinMiddleware? Я вижу, что в источнике Katana некоторые из классов промежуточного программного обеспечения происходят от OwinMiddleware, а некоторые нет.

  2. Я могу видеть заголовки запросов в порядке. Настройка заголовка ответа или кода состояния после Next.Invoke в моем промежуточном программном обеспечении не влияет на ответ, возвращаемый клиенту. Но если я установил заголовок ответа или статус перед вызовом Next.Invoke, ответ с заголовками и статус, который я установил, возвращаются клиенту. Каков правильный способ их настройки?

ответ

25
  1. Да, выводя из OwinMiddleware рекомендуется. Причина, по которой некоторые классы промежуточного ПО не выводятся из OwinMiddleware, заключается в том, что они еще не переключились, потому что класс был введен недавно. Или во избежание сбоя сборки по какой-либо причине зависит от сборки Microsoft.Owin.

  2. Вероятная причина, по которой настройка ответа на запрос после вызова Invoke on Next не работает, заключается в том, что HTTP-заголовок ответа отправляется, как только кто-либо начинает писать поток тела ответа. Таким образом, любые изменения кода состояния или заголовков HTTP после того, как компонент промежуточного программного обеспечения начнет записываться в тело ответа, не будет иметь никакого эффекта.

Что вы можете попробовать сделать, это использовать обратный вызов OnSendingHeaders, который предоставляет OWIN. Вот как вы можете это использовать:

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); 
} 

Кредит на biscuit314 для обновления моего ответа.

+0

Благодаря Юсеф. Для точки №2 есть ли пример кода в источнике Katana или где-то еще, на что я могу смотреть, из лучшей практики pt зрения? Я считаю, что то, о чем я прошу, является довольно распространенной потребностью, и каждый должен использовать этот поток, чтобы просто настроить заголовок ответа, если мы используем промежуточное ПО OWIN? Любые указатели будут оценены. – Badri

+0

Я могу решить проблему, следуя вашим предложениям, но не так ли? Я имею в виду, что это слишком большая работа, чтобы просто настроить заголовок ответа на выходе, особенно если он используется для обработчика сообщений веб-API. – Badri

+3

Обновлен ответ более простым методом. Пожалуйста, дайте мне знать, если это сработает. –

7

Я попытался отредактировать отличный ответ Youssef, чтобы исправить незначительную ошибку и обновить пример использования OwinMiddleware.

Редактирование было отклонено (хорошо, одобрено одним, отклонено одним за слишком незначительное и отклонено двумя за то, что оно слишком велико).

Вот что версия кода Юсеф в:

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

новый OWIN работает только с этим переопределением – Raffaeu