2013-07-07 57 views
22

我的OWIN中間件就是這樣。 (框架是ASP.NET Web API)。從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. 調用onvoke on next之後設置響應的可能原因不起作用,即任何人開始寫入響應正文流時都會發送響應HTTP頭。因此,在中間件組件開始寫入響應主體之後,狀態碼或HTTP標頭的任何更改都不會產生任何影響。

你可以嘗試的是使用OWIN提供的OnSendingHeaders回調函數。以下是如何使用它:

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

貸款餅乾314更新我的答案。

+0

謝謝優素福。對於第二點,從最佳實踐角度來看,Katana來源或其他地方有沒有示例代碼?我相信,我所要求的是一個相當普遍的需求,如果我們使用OWIN中間件,每個人都應該做這個流切換來設置一個響應頭文件?任何指針將不勝感激。 – Badri

+0

我可以按照你的建議來解決問題,但不是一個簡單的方法嗎?我的意思是這樣做太多了,只需在出口設置響應頭,特別是如果使用Web 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