C# 如何将 Web API 以外的所有内容路由到 /index.html
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19643001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to route EVERYTHING other than Web API to /index.html
提问by Scott R. Frost
I've been working on an AngularJSproject, inside of ASP.NET MVC using Web API. It works great except when you try to go directly to an angular routed URL or refresh the page. Rather than monkeying with server config, I thought this would be something I could handle with MVC's routing engine.
我一直在使用 Web API 在 ASP.NET MVC 内部开发一个AngularJS项目。除非您尝试直接转到角度路由 URL 或刷新页面,否则它非常有效。与其玩弄服务器配置,我认为这将是我可以用MVC 的路由引擎处理的事情。
Current WebAPIConfig:
当前的 WebAPIConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"^[0-9]+$" }
);
config.Routes.MapHttpRoute(
name: "ApiWithActionAndName",
routeTemplate: "api/{controller}/{action}/{name}",
defaults: null,
constraints: new { name = @"^[a-z]+$" }
);
config.Routes.MapHttpRoute(
name: "ApiWithAction",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "Get" }
);
}
}
Current RouteConfig:
当前路由配置:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute(""); //Allow index.html to load
routes.IgnoreRoute("partials/*");
routes.IgnoreRoute("assets/*");
}
}
Current Global.asax.cs:
当前 Global.asax.cs:
public class WebApiApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.None,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
};
}
}
GOAL:
目标:
/api/* continues to go to WebAPI, /partials/, and /assets/all go to file system, absolutely anything else gets routed to /index.html, which is my Angular single page app.
/api/* 继续转到 WebAPI, /partials/和 /assets/都转到文件系统,绝对其他任何内容都路由到 /index.html,这是我的 Angular 单页应用程序。
--EDIT--
- 编辑 -
I seem to have gotten it working. Added this to the BOTTOM OFRouteConfig.cs:
我似乎已经让它工作了。将此添加到RouteConfig.cs的底部:
routes.MapPageRoute("Default", "{*anything}", "~/index.html");
And this change to the root web.config:
对根 web.config 的更改:
<system.web>
...
<compilation debug="true" targetFramework="4.5.1">
<buildProviders>
...
<add extension=".html" type="System.Web.Compilation.PageBuildProvider" /> <!-- Allows for routing everything to ~/index.html -->
...
</buildProviders>
</compilation>
...
</system.web>
However, it smells like a hack. Any better way to do this?
然而,它闻起来像黑客。有没有更好的方法来做到这一点?
采纳答案by Trevor Elliott
Use a wildcard segment:
使用通配符段:
routes.MapRoute(
name: "Default",
url: "{*anything}",
defaults: new { controller = "Home", action = "Index" }
);
回答by BotanMan
Suggest more native approach
建议更原生的方法
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1"/>
<error statusCode="404" prefixLanguageFilePath="" path="/index.cshtml" responseMode="ExecuteURL"/>
</httpErrors>
</system.webServer>
回答by Andreas
Well, I just removed the RouteConfig.RegisterRoutes(RouteTable.Routes);
call in Global.asax.cs
and now whatever url I enter, if the resource exists, it will be served. Even the API Help Pages still work.
好吧,我刚刚删除了RouteConfig.RegisterRoutes(RouteTable.Routes);
调用Global.asax.cs
,现在无论我输入什么 url,如果资源存在,它将被提供。甚至 API 帮助页面仍然有效。
回答by Sonic Soul
in my case none of these approaches worked. i was stuck in 2 error message hell. either this type of page is not servedor some sort of 404.
就我而言,这些方法都不起作用。我被困在 2 个错误消息地狱中。要么不提供这种类型的页面,要么是某种 404。
url rewrite worked:
网址重写有效:
<system.webServer>
<rewrite>
<rules>
<rule name="AngularJS" stopProcessing="true">
<match url="[a-zA-Z]*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
...
notice i matched on [a-zA-Z] because i don't want to rewrite any of the .js .map etc urls.
注意我匹配 [a-zA-Z] 因为我不想重写任何 .js .map 等网址。
this worked in VS out of hte box, but in IIS you may need to install a url-rewrite module https://www.iis.net/downloads/microsoft/url-rewrite
这在 VS 开箱即用,但在 IIS 中,您可能需要安装 url-rewrite 模块https://www.iis.net/downloads/microsoft/url-rewrite
回答by John
I had a similar approach as the top few answers, but the downside is if someone is making an API call incorrectly, they'll end up getting that index page back instead of something more useful.
我有一个与前几个答案类似的方法,但缺点是如果有人错误地进行了 API 调用,他们最终会得到那个索引页而不是更有用的东西。
So I've updated mine such that it will return my index page for any request not starting with /api:
所以我更新了我的,这样它就会为任何不以 /api 开头的请求返回我的索引页面:
//Web Api
GlobalConfiguration.Configure(config =>
{
config.MapHttpAttributeRoutes();
});
//MVC
RouteTable.Routes.Ignore("api/{*anything}");
RouteTable.Routes.MapPageRoute("AnythingNonApi", "{*url}", "~/wwwroot/index.html");