如何将Web API以外的所有内容路由到/index.html

Sco*_*ost 53 c# asp.net asp.net-mvc asp.net-mvc-4 angularjs

我一直在使用Web API在ASP.NET MVC内部开发一个AngularJS项目.除非您尝试直接转到角度路由URL或刷新页面,否则它的效果很好.我认为这可以用MVC的路由引擎来处理,而不是用服务器配置进行修改.

目前的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" }
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

当前的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/*");
    }
}
Run Code Online (Sandbox Code Playgroud)

当前的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,
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

目标:

/ api/*继续转到WebAPI,/ partials/,和/ assets / all转到文件系统,绝对其他任何东西都被路由到/index.html,这是我的Angular单页面应用程序.

- 编辑 -

我似乎已经开始工作了.将此添加到RouteConfig.cs 的BOTTOM:

 routes.MapPageRoute("Default", "{*anything}", "~/index.html");
Run Code Online (Sandbox Code Playgroud)

这个改为root 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>
Run Code Online (Sandbox Code Playgroud)

然而,它闻起来像一个黑客.有更好的方法吗?

Tre*_*ott 28

使用通配符段:

routes.MapRoute(
    name: "Default",
    url: "{*anything}",
    defaults: new { controller = "Home", action = "Index" }
);
Run Code Online (Sandbox Code Playgroud)

  • 通配符可能有用,我可以将它转到平面文件而不是MVC控制器吗?或者,我如何制作一个带有Index操作的Home控制器,该操作将执行传递给index.html,同时保留他们输入的URL(例如/ something/edit/123)? (4认同)

Bot*_*Man 12

建议更多原生方法

<system.webServer>
    <httpErrors errorMode="Custom">
        <remove statusCode="404" subStatusCode="-1"/>
        <error statusCode="404" prefixLanguageFilePath="" path="/index.cshtml" responseMode="ExecuteURL"/>
    </httpErrors>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)


Son*_*oul 5

就我而言,这些方法都没有奏效.我陷入了2个错误信息地狱.要么是这种类型的页面没有提供,要么是某种类型的404.

网址重写工作:

<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>
    ...
Run Code Online (Sandbox Code Playgroud)

注意我在[a-zA-Z]上匹配,因为我不想重写任何.js .map等网址.

这在VS的hte框中工作,但在IIS中你可能需要安装一个url-rewrite模块https://www.iis.net/downloads/microsoft/url-rewrite


Joh*_*ohn 5

我采用了与前几个答案类似的方法,但缺点是如果有人错误地进行 API 调用,他们最终会取回索引页面而不是更有用的内容。

所以我更新了我的,这样它将针对任何不以 /api 开头的请求返回我的索引页面:

        //Web Api
        GlobalConfiguration.Configure(config =>
        {
            config.MapHttpAttributeRoutes();
        });

        //MVC
        RouteTable.Routes.Ignore("api/{*anything}");
        RouteTable.Routes.MapPageRoute("AnythingNonApi", "{*url}", "~/wwwroot/index.html");
Run Code Online (Sandbox Code Playgroud)