Asp.net

包裝 StaticFileMiddleware 以重定向 404 錯誤

  • April 17, 2016

我正在嘗試將自定義中間件注入到我的 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

引用自:https://stackoverflow.com/questions/25916851