我正在尝试将自定义中间件注入我的OWIN管道,该管道包装了MS提供的StaticFileMiddleware,以支持AngularJS中的
HTML 5模式.我一直在关注这个指南:
http://geekswithblogs.net/shaunxu/archive/2014/06/10/host-angularjs-html5mode-in-asp.net-vnext.aspx
从我可以收集到的如何工作,我的中间件将请求传递给静态文件中间件,然后如果它无法解决这些请求(即,请求HTML 5角度路径,“/无论如何“),它返回基本角度页面,以便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还是自我主机.如果您使用的是IIS,那么与使用owin中间件相比,有一个更清洁/更快的解决方案:
您可以使用IIS重写引擎,在Web配置中复制以下内容.
您可以使用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