包装StaticFileMiddleware重定向404错误 [英] Wrapping StaticFileMiddleware to redirect 404 errors
问题描述
我想注入一个定制的中间件到我OWIN管道封装了可从MS StaticFileMiddleware
以支持HTML 5模式AngularJS。我一直遵循本指南:<一href=\"http://geekswithblogs.net/shaunxu/archive/2014/06/10/host-angularjs-html5mode-in-asp.net-vnext.aspx\">http://geekswithblogs.net/shaunxu/archive/2014/06/10/host-angularjs-html5mode-in-asp.net-vnext.aspx
这是我所知的这是如何工作的,我的中间件沿请求传递给静态文件的中间件,然后如果它不能解析这些请求(例如,对于HTML 5角路径的请求, /无所谓),它,而不是返回基地角页面,以便为HTML 5路径硬请求将正常工作。
我的问题是调用中间件内的结果似乎总是一个200状态code,即使在我的浏览器,我收到了404,这让我抓我的头。这里是我的code,以供参考:
公共静态类AngularServerExtension
{
公共静态IAppBuilder UseAngularServer(这IAppBuilder建设者,ROOTPATH串,串entryPath)
{
VAR的选择=新AngularServerOptions()
{
FileServerOptions =新FileServerOptions()
{
EnableDirectoryBrowsing =假,
FileSystem的=新PhysicalFileSystem(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory,ROOTPATH))
},
EntryPath =新PathString(entryPath)
}; builder.UseDefaultFiles(options.FileServerOptions.DefaultFilesOptions);
返回builder.Use(新Func键&LT; AppFunc,AppFunc&GT;(下一=&gt;新建AngularServerMiddleware(接下来,期权).Invoke));
}
}公共类AngularServerMiddleware
{
私人只读AngularServerOptions _options;
私人只读AppFunc _next;
私人只读StaticFileMiddleware _innerMiddleware; 公共AngularServerMiddleware(AppFunc接下来,AngularServerOptions选项)
{
_next =下一个;
_options =选择; _innerMiddleware =新StaticFileMiddleware(_next,options.FileServerOptions.StaticFileOptions);
} 公共异步任务调用(IDictionary的&LT;字符串对象&gt;环境)
{
IOwinContext语境=新OwinContext(环境);
//试图解决与默认的静态文件中间件请求
等待_innerMiddleware.Invoke(环境);
的Debug.WriteLine(context.Request.Path +:+ context.Response.Status code);
// ***就在这里,我希望404,但我得到调试时200,
//即使我的浏览器最终会返回一个404 //为根路径途径,如果状态code是404
//和需要支持的角度html5mode
如果(context.Response.Status code == 404安培;&安培; _options.Html5Mode)
{
context.Request.Path = _options.EntryPath;
等待_innerMiddleware.Invoke(环境);
Console.WriteLine(&GT;&gt;中+ context.Request.Path +:+ context.Response.Status code);
}
}
}
公共类AngularServerOptions
{
公共FileServerOptions FileServerOptions {搞定;组; } 公共PathString EntryPath {搞定;组; } 公共BOOL Html5Mode
{
得到
{
返回EntryPath.HasValue;
}
} 公共AngularServerOptions()
{
FileServerOptions =新FileServerOptions();
EntryPath = PathString.Empty;
}
}
从你的问题我不知道您是否使用IIS或selfhost。如果您使用的是IIS,有比owin中间件搞乱更清洁/更快的解决方案:
您可以使用IIS重写引擎,复制你的web配置里面以下。
&LT; system.webServer&GT;&LT;&改写GT;
&LT;规则与GT;
&LT;! - 重定向选择流量指标 - &GT;
&LT;规则名称=索引规则stopProcessing =真&GT;
&LT;*匹配URL = /&GT;
&LT;条件logicalGrouping =MatchAll&GT;
&LT;添加输入={} REQUEST_FILENAME使用MatchType =ISFILE否定=TRUE/&GT;
&LT;添加输入={} REQUEST_URI使用MatchType =模式模式=^ / API /否定=TRUE/&GT;
&所述; /条件&gt;
&lt;作用TYPE =重写URL =/ index.html的/&GT;
&LT; /规则&GT;
&LT; /规则&GT;
&LT; /重写&GT;
...
&LT; /system.webServer>
这行允许所有文件都被正常送达:
&LT;添加输入={} REQUEST_FILENAME使用MatchType =ISFILE否定=TRUE/&GT;
这行允许正常服务的API
&LT;添加输入={} REQUEST_URI使用MatchType =模式模式=^ / API /否定=TRUE/&GT;
其他的一切得到的index.html
I'm trying to inject a custom middleware into my OWIN pipeline that wraps the StaticFileMiddleware
available from MS in order to support HTML 5 mode in AngularJS. I've been following this guide: http://geekswithblogs.net/shaunxu/archive/2014/06/10/host-angularjs-html5mode-in-asp.net-vnext.aspx
From what I can gather of how this is supposed to work, my middleware is passing along requests to the static file middleware, and then if it can't resolve those requests (i.e., a request for an HTML 5 angular path, "/whatever"), it instead returns the base angular page so that a hard request for an HTML 5 path will work.
My problem is that the result of invoking the inner middleware always seems to be a 200 status code, even though in my browser I get a 404, which leaves me scratching my head. Here's my code for reference:
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;
}
}
From your question I am not sure whether you are using IIS or selfhost. If you are using IIS, there is a much cleaner/faster solution than messing up with owin middleware: You can use IIS rewrite engine, copy the following inside your web config.
<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>
This line allows all files to be served normally:
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
this line allows the api to be served normally
<add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" negate="true" />
Everything else gets index.html
这篇关于包装StaticFileMiddleware重定向404错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!