tutorial net mvc framework example español asp c# asp.net asp.net-mvc asp.net-mvc-4 angularjs

c# - net - Cómo enrutar TODO lo que no sea API web a/index.html



asp.net mvc 5 angularjs tutorial español (5)

He estado trabajando en un proyecto AngularJS , dentro de ASP.NET MVC usando la API web. Funciona muy bien, excepto cuando intenta ir directamente a una URL enrutada angular o actualizar la página. En lugar de monkeying con la configuración del servidor, pensé que esto sería algo que podría manejar con el motor de enrutamiento de MVC .

WebAPIConfig actual:

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:

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

GOL:

/ api / * continúa yendo a WebAPI, / partials / , y / assets / todo va al sistema de archivos, absolutamente todo lo demás se enruta a /index.html, que es mi aplicación Angular de una sola página.

--EDITAR--

Parece que lo he hecho funcionar. Se agregó esto al FONDO DE RouteConfig.cs:

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

Y este cambio a la raíz 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>

Sin embargo, huele como un truco. ¿Alguna mejor manera de hacer esto?


Bueno, acabo de eliminar RouteConfig.RegisterRoutes(RouteTable.Routes); llame a Global.asax.cs y ahora sea cual sea la URL que ingrese, si el recurso existe, se publicará. Incluso las páginas de ayuda de API aún funcionan.


Sugerir un enfoque más nativo

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


Tenía un enfoque similar al de las mejores respuestas, pero la desventaja es que si alguien realiza una llamada a la API incorrectamente, terminará recuperando esa página de índice en lugar de algo más útil.

Así que actualicé el mío de modo que devuelva mi página de índice para cualquier solicitud que no comience con / api:

//Web Api GlobalConfiguration.Configure(config => { config.MapHttpAttributeRoutes(); }); //MVC RouteTable.Routes.Ignore("api/{*anything}"); RouteTable.Routes.MapPageRoute("AnythingNonApi", "{*url}", "~/wwwroot/index.html");


Use un segmento comodín:

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


en mi caso ninguno de estos enfoques funcionó. estaba atrapado en 2 infierno de mensaje de error. este tipo de página no se sirve o algún tipo de 404.

reescritura url funcionó:

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

note que coincidí en [a-zA-Z] porque no quiero reescribir ninguna de las URL de .js .map etc.

esto funcionó en VS fuera de la caja hte, pero en IIS es posible que deba instalar un módulo url-rewrite https://www.iis.net/downloads/microsoft/url-rewrite