Asp.net
包裝 StaticFileMiddleware 以重定向 404 錯誤
我正在嘗試將自定義中間件注入到我的 OWIN 管道中,該管道包裝了
StaticFileMiddlewareMS 中的可用中間件,以支持 AngularJS 中的 HTML 5 模式。我一直在關注本指南: http: //geekswithblogs.net/shaunxu/archive/2014/06/10/host-angularjs-html5mode-in-asp.net-vnext.aspx根據我所能收集到的關於它應該如何工作的資訊,我的中間件正在將請求傳遞給靜態文件中間件,然後如果它無法解析這些請求(即,對 HTML 5 角度路徑的請求,“/whatever “),而是返回基本的角度頁面,以便對 HTML 5 路徑的硬請求將起作用。
我的問題是呼叫內部中間件的結果似乎總是一個 200 狀態碼,即使在我的瀏覽器中我得到一個 404,這讓我摸不著頭腦。這是我的程式碼供參考:
public static class AngularServerExtension { public static IAppBuilder UseAngularServer(this IAppBuilder builder, string rootPath, string entryPath) { var options = new AngularServerOptions() { FileServerOptions = new FileServerOptions() { EnableDirectoryBrowsing = false, FileSystem = new PhysicalFileSystem(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, rootPath)) }, EntryPath = new PathString(entryPath) }; builder.UseDefaultFiles(options.FileServerOptions.DefaultFilesOptions); return builder.Use(new Func<AppFunc, AppFunc>(next => new AngularServerMiddleware(next, options).Invoke)); } } public class AngularServerMiddleware { private readonly AngularServerOptions _options; private readonly AppFunc _next; private readonly StaticFileMiddleware _innerMiddleware; public AngularServerMiddleware(AppFunc next, AngularServerOptions options) { _next = next; _options = options; _innerMiddleware = new StaticFileMiddleware(_next, options.FileServerOptions.StaticFileOptions); } public async Task Invoke(IDictionary<string, object> environment) { IOwinContext context = new OwinContext(environment); // try to resolve the request with default static file middleware await _innerMiddleware.Invoke(environment); Debug.WriteLine(context.Request.Path + ": " + context.Response.StatusCode); // *** Right here is where I would expect a 404 but I get a 200 when debugging, // even though my browser eventually returns a 404 // route to root path if the status code is 404 // and need support angular html5mode if (context.Response.StatusCode == 404 && _options.Html5Mode) { context.Request.Path = _options.EntryPath; await _innerMiddleware.Invoke(environment); Console.WriteLine(">> " + context.Request.Path + ": " + context.Response.StatusCode); } } } public class AngularServerOptions { public FileServerOptions FileServerOptions { get; set; } public PathString EntryPath { get; set; } public bool Html5Mode { get { return EntryPath.HasValue; } } public AngularServerOptions() { FileServerOptions = new FileServerOptions(); EntryPath = PathString.Empty; } }
根據您的問題,我不確定您使用的是 IIS 還是 selfhost。如果您使用的是 IIS,有一個比使用 owin 中間件更乾淨/更快的解決方案:您可以使用 IIS 重寫引擎,將以下內容複製到您的 Web 配置中。
<system.webServer> <rewrite> <rules> <!--Redirect selected traffic to index --> <rule name="Index Rule" stopProcessing="true"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" negate="true" /> </conditions> <action type="Rewrite" url="/index.html" /> </rule> </rules> </rewrite> ... </system.webServer>此行允許正常提供所有文件:
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />此行允許 api 正常服務
<add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" negate="true" />其他所有內容都獲取 index.html