endpoints.MapFallbackToFile("index.html") messes up routing in asp.net core project - asp.net-core

The solution has a web-api project that is also the host for a blazor-webassembly front-end.
With this config all works fine. WebApi endpoint get hit correctly when called from postman.
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
When adding a MapFallBackToFile suddenly some Api-Endpoint do not get hit anymore but serve that default file.
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
endpoints.MapFallbackToFile("index.html");
});
The reason for adding this fallback : serve as landing page for the Blazor front-end.
Any suggestions ?

Related

How to Default Route in ASP.NET Core 6 MVC?

I'm trying to learn ASP.NET Core 6, and now following a tutorial using ASP.NET Core 2. After adding the controller phase they delete this line from the startup file
app.run(async (context) = await context.response.writeasync("hello world"))
and add
app.UseMvcWithDefaultRoute();
so they can see the views.
As you know there is no startup file in ASP.NET Core 6, and I don't know what to do at this point.
I searched the internet a lot and have nothing.
I try to adjust the code in the program file like that
app.MapGet("/", () => app.UseMvcWithDefaultRoute);
but that does not work.
In asp.net core6 we define the default route like this:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
You can read Routing to controller actions in ASP.NET Core to know more.

aspnet core get configured route templates

is it possibile retrive the endpoint templates configured on the Configure method in the StartUp.cs ?
app.UseEndpoints(endpoints =>
{
endpoints.MapDynamicControllerRoute<TranslationTransformer>("{tenant}/{slug}");
endpoints.MapDynamicControllerRoute<TranslationTransformer>("{tenant}/{typology}/{slug}/{id}");
});
I try to export the template section for passing passing it to an /routing api
Thanks in advance.

Route Name for Conventions-Based Routing

I am using conventions-based routing (as opposed to attribute-based routing) using ASP.NET CORE 3. I know it is possible to get the chosen route name when using attribute-based routing by using the AttributeRouteInfo.Name property. How do I do the same when using conventions-based routing (by this I mean setting up the routes in Startup.cs)? I can't find any explanation or properties.
The way I found to do it is like this, and it works with both attribute routing and conventional routing. Put this in the controller's action method:
Endpoint endpoint = ControllerContext.HttpContext.Features.Get<IEndpointFeature>()?.Endpoint;
String routeName = endpoint?.Metadata.GetMetadata<RouteNameMetadata>().RouteName;
This technique does not require you to add custom objects to the MapControllerRoute() as in Zhi Lv's approach.
From your description, I assume your application is an Asp.net Core MVC application, and in the Startup.Configure method, you are using the MapControllerRoute() or MapAreaControllerRoute() method to set the conventional route, like this:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
And at present, you want to get the route name ("default") in the controller method, right?
If that is the case, as a workaround, you could use the MapControllerRoute() and MapAreaControllerRoute() method's defaults parameter to store the route name.
For example:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default route",
pattern: "{controller=Reports}/{action=Index}/{id?}",
new { routeName= "default route" }); //add the routeName.
endpoints.MapRazorPages();
});
Then, in the controller method, you could get the value from the ControllerContext.RouteData, like this:
public IActionResult Index()
{
var contenxt = ControllerContext.RouteData.Values;
if (contenxt.Keys.Contains("routeName"))
{
var routename = contenxt["routeName"];
}
return View();
}
The screenshot as below:

favicon.ico not found when using Areas in ASP.NET Core

When I add "areas" route mapping, the browser's request to /favicon.ico which is in the root of wwwroot folder is returning the error: "The view 'Index' was not found. The following locations were searched: /Areas/favicon.ico/Views/Home/Index.cshtml"
No error prior to adding the "areas" endpoint route mapping.
app.UseAuthentication();
app.UseStatusCodePages();
app.UseRouting();
app.UseAuthorization();
app.UseStaticFiles();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
It looks like the routing engine is confusing favicon.ico for a controller. Any idea how to fix this?
You should move the UseStaticFiles() above the UseRouting() call.
Since middleware executes from top to bottom, in your case UseRouting is called first. When the UseRouting middleware executes, it determines the route to call based on the endpoint mappings that you passed to UseEndpoints. So it sees the route /favicon.ico and tries to match it with one of your MVC routes ultimately picking favicon.ico as the name of an area (so the full route would have been /favicon.ico/Home/Index. And for that, ASP.NET Core obviously cannot find a matching view.
But what you want to do instead is have the static files middleware execute first so that it serves all the static files it can find before it attempts to parse the remaining routes as MVC routes.
So just move the UseStaticFiles() call up:
app.UseStatusCodePages();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
You might also want to move the static files before authentication to make sure thtat all users can also access your static files.

How do I configure routing for MVC and SignalR in an ASP.NET Core project?

I'm trying to build a web app with ASP.NET Core 2.1.0-preview1 and ASP.NET Core SignalR 1.0.0-alpha1 with an Angular4 client. So far I've been able to muddle through and can actually open a SignalR web socket connection from within the client. That came at a price, though, here's an excerpt of my Startup.cs:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
/*routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });*/
});
app.UseWebSockets();
app.UseSignalR(routes =>
{
routes.MapHub<Feed>("feed");
});
As you can see, I had to disable the "spa-fallback" route, if I didn't do that SignalR would receive plain HTML instead of JSON. The drawback of that, of course, is that I have to enter the exact URL (localhost:12345/home/index, for example) now, which sucks.
So my question is, how can I make MVC routing and SignalR routing live side by side?
You need to put UseSignalR before UseMvc otherwise the fallback route will be registered before routes added by UseSignalR.