Подтвердить что ты не робот

Как перенаправить ВСЕ, кроме веб-API, в/index.html

Я работал над проектом AngularJS внутри ASP.NET MVC с использованием веб-API. Он отлично работает, за исключением случаев, когда вы пытаетесь перейти непосредственно к URL-адресу angular или обновить страницу. Вместо того, чтобы обезвреживать конфигурацию сервера, я подумал, что это будет что-то, что я мог бы обработать с помощью механизма маршрутизации 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" }
        );
    }
}

Текущий 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:

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,
        };
    }
}

ЗАДАЧА:

/api/* по-прежнему переходит в WebAPI,/partials/и/assets/all переходит в файловую систему, абсолютно что-либо еще перенаправляется в /index.html, что является моим angular одностраничным приложением.

- EDIT -

Кажется, я получил работу. Добавлено это в BOTTOM OF RouteConfig.cs:

 routes.MapPageRoute("Default", "{*anything}", "~/index.html");

И это изменение в корневой 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>

Тем не менее, он пахнет румянцем. Любой лучший способ сделать это?

4b9b3361

Ответ 1

Используйте подстановочный сегмент:

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

Ответ 2

Предложите более удобный подход

<system.webServer>
    <httpErrors errorMode="Custom">
        <remove statusCode="404" subStatusCode="-1"/>
        <error statusCode="404" prefixLanguageFilePath="" path="/index.cshtml" responseMode="ExecuteURL"/>
    </httpErrors>
</system.webServer>

Ответ 3

в моем случае ни один из этих подходов не работал. я застрял в 2 сообщениях об ошибке. либо этот тип страницы не обслуживается или какой-то 404.

Работа с URL:

<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>
    ...

Обратите внимание, что я сопоставлен с [a-zA-Z], потому что я не хочу переписывать ни один из URL-адресов .js.map и т.д.

это работало в VS вне поля hte, но в IIS вам может потребоваться установить модуль url-rewrite https://www.iis.net/downloads/microsoft/url-rewrite

Ответ 4

У меня был такой же подход, как и самые верные ответы, но недостатком является то, что если кто-то неправильно вызывает API-интерфейс, они вернут эту индексную страницу вместо чего-то более полезного.

Итак, я обновил мой, чтобы он возвращал мою индексную страницу для любого запроса, не начинающегося с /api:

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

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

Ответ 5

Ну, я просто удалил вызов RouteConfig.RegisterRoutes(RouteTable.Routes); в Global.asax.cs и теперь любой URL-адрес, который я вводил, если ресурс существует, он будет обслуживаться. Даже страницы справки API все еще работают.