I've been working on an AngularJS project, 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.
Current 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:
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.
--EDIT--
I seem to have gotten it working. Added this to the BOTTOM OF RouteConfig.cs:
routes.MapPageRoute("Default", "{*anything}", "~/index.html");
And this change to the 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>
However, it smells like a hack. Any better way to do this?
Conventional or Traditional Routing also is a pattern matching system for URL that maps incoming request to the particular controller and action method. We set all the routes in the RouteConfig file. RouteConfig file is available in the App_Start folder. We need to register all the routes to make them operational.
It routes an incoming HTTP request to a particular action method on a Web API controller. Web API supports two types of routing: Convention-based Routing. Attribute Routing.
We can override the RoutePrefix on a method, using the tilde(~) sign. We can easily define parameterized templates in the attribute based routing. We can have parameters defined in-between the API request URLs.
If you are familiar with ASP.NET MVC, Web API routing is very similar to MVC routing. The main difference is that Web API uses the HTTP verb, not the URI path, to select the action. You can also use MVC-style routing in Web API.
Use a wildcard segment:
routes.MapRoute( name: "Default", url: "{*anything}", defaults: new { controller = "Home", action = "Index" } );
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With