我的中間件類在不同的類庫項目中,而控制器在不同的項目中。我試圖做的,如果特定條件不符合然後重定向到中間件的自定義控制器/操作方法。來自中間件的呼叫控制器的操作方法
但是,我不能用Response.Redirect方法做到這一點。
我該如何在中間件類中做到這一點?
對此有任何幫助表示讚賞!
Rohit
我的中間件類在不同的類庫項目中,而控制器在不同的項目中。我試圖做的,如果特定條件不符合然後重定向到中間件的自定義控制器/操作方法。來自中間件的呼叫控制器的操作方法
但是,我不能用Response.Redirect方法做到這一點。
我該如何在中間件類中做到這一點?
對此有任何幫助表示讚賞!
Rohit
看來你是因爲錯誤的原因使用了中間件。
我建議你通過簡單地將它寫入響應流(而不是轉發到Next()
)來讓中間件返回一個(非常小的)404,或者不要在中間件中完成此操作,而是在在您的MVC應用程序中全球註冊了IActionFilter
。
我已經解釋了在評論上述建議的理由,但我認爲要提升到實際的答案是足夠重要:
在中間件管道,希望每個組件是爲儘可能獨立。幾件事情啓用OWIN此鬆耦合:
的輸入,並且輸出從,每個組件具有相同的格式,是否有收到10個其他中間件組件,或者根本沒有
的約定是,該管道的每一部分都可以做的三件事情的一個或多個,順序如下:
閱讀(修改)傳入的請求。
決定完全處理請求,或轉發處理到下一個組件。
寫入響應流。
當粘到這些約定,它變得非常容易編寫,分解和重新組成從可重用中間件組件管線。 (希望請求日誌記錄?只需在管道的起始處連接一箇中間件組件,想要在整個板上使用一些通用的身份驗證邏輯?在管道的auth階段添加一個組件。想要切換到不同的日誌記錄框架?要想在微服務的生態系統中應用相同的日誌記錄,可以重新使用組件Etcetera,ad infinum ...)這很有效,因爲組件都在它們的邊界之內,並且與Web服務器本身可以理解。
ASP.NET WebAPI看起來可能是一個不同的野獸,但實際上它只是另一個OWIN組件,它總是被配置爲處理請求,並且永遠不會轉發到下一個組件(因此它們使它變得困難在管道中的WebApi之後註冊一個組件......)。
你想要做什麼,打破了第二點的合同 - 你想告訴下一個組件如何處理請求。 但這並不取決於你 - 它取決於下一個組件。
能否請你提供一個404和IActionFilter的小例子?謝謝 ! – Rohit
要寫入回覆,請參閱[這個Q/A](http://stackoverflow.com/questions/32532058/how-do-i-ask-owin-katana-to-write-headers-to-the-output-stream)。對於'IActionFilter'的例子,看看[這裏](https://damienbod.com/2014/01/04/web-api-2-using-actionfilterattribute-overrideactionfiltersattribute-and-ioc-injection/) –
你能解釋一下爲什麼他的用例不適合中間件。 –
這是檢查請求並重定向的中間件。它適用於嵌入式中間件或中間件類。
public void Configure(IApplicationBuilder app)
{
// use inline middleware
app.Use(async (context, next) =>
{
// if specific condition does not meet
if (context.Request.Path.ToString().Equals("/foo"))
{
context.Response.Redirect("path/to/controller/action");
}
else
{
await next.Invoke();
}
});
// or use a middleware class
app.UseMiddleware<RedirectMiddleware>();
app.UseMvc();
}
這裏是中間件類。
public class RedirectMiddleware
{
private readonly RequestDelegate _next;
public RedirectMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
// if specific condition does not meet
if (context.Request.Path.ToString().Equals("/bar"))
{
context.Response.Redirect("path/to/controller/action");
}
else
{
await _next.Invoke(context);
}
}
}
有關更多信息,請參閱Docs » Fundamentals » Middleware。
條件是什麼?它是認證/授權,還是其他?如果它是auth,你可能想要返回'401'或'403'(取決於它是認證還是授權失敗),如果是別的東西,你可能不想首先在中間件中執行它。你可以再詳細一點嗎? –
@TomasLycken是的,它與認證/授權無關,如果沒有找到特定的客戶端/租戶,則重定向到某些控制器的操作方法以顯示錯誤消息。要從httpcontext獲取客戶名稱,邏輯是寫在中間件 – Rohit