Change the "/api" part of the url in ASP.Net Core - asp.net-core

When I run a .NET Core Web API project, I get a URL that looks like this: http://localhost:5000/api/...
How can I change the /api/ part of the URL to something else? i.e. - http://localhost:5000/myservice/...
I am using Kestrel as my web host.

It depends on how you have the project setup. By default I believe it uses attribute routing. In your controller you should see something like this
[Route("api/[controller]")]
public class ValuesController : Controller
{
Where the [Route("api/[controller]")] would just need to be changed to [Route("myservice/[controller]")]
If you wanted to do it Globally you could do it like this.
app.UseMvc(routes =>
{
routes.MapRoute("default", "myservice/{controller=values}/{action=get}/{id?}");
});
Although I myself don't use this, and it's not exactly what MS Recommends for a Web Api. You can read more here.
Mixed Routing
MVC applications can mix the use of conventional routing and attribute routing. It's typical to use conventional routes for controllers serving HTML pages for browsers, and attribute routing for controllers serving REST APIs.

You could just install microsoft.aspnetcore.http.abstractions nuget package and use UsePathBaseExtensionsextension method on IApplicationBuilder in your Startup.Configure method like so:
app.UsePathBase("/api/v1");

Related

Only Map existing Blazor Pages(Razor Components) in the pipeline?

The usual pattern for Blazor (server) apps, is that at the end pf program.cs there is app.MapFallbackToPage("/_Host");
That will result in ALL request paths, that match no earlier endpoint, executing the Blazor App. Sure the Blazor App has a <NotFound> Renderfragment, but that will still result in establishing the SignalR and so on. What if I want to display a static file (.html) from wwwroot or a specfic RAZOR PAGE (.cshtml), which doesnt establlish a websocket for all those cases where the route does NOT EXIST IN ANY BLAZOR PAGE ???
NavigationManager.NavigateTo cannot be used directly inside the BuildRenderTree markup of the <NotFound> ... I could maybe put a component inside there that redirects OnInitialized ... but that would still first require the SignalR.
How can I completely avoid Blazor/SignalR for URLs that don't exist in the Blazor App ?
Idea: I could try to add ALL POSSIBLE Blazor-routes as fallbacks and the most general fallback to some static file or Razor Page... but that seems LIKE A LOT OF DOUBLE WORK and very error prone... is there no way?
app.MapFallbackToPage("~/Admin/{*clientroutes:nonfile}", "/_Host");
app.MapFallbackToPage("~/SomeRoute/More/{*clientroutes:nonfile}", "/_Host");
app.MapFallbackToPage("~/SomePage/{*clientroutes:nonfile}", "/_Host");
app.MapFallbackToPage("/NotValidRoute");
Edit:
#Reason:
I wanted to have a single fallback page (razor page or static) for all routes/urls that don't match any target in the app. But sadly as it seems, that conflicts with blazor'S client side routing. since the server-side routing does not know, which routes should be handled by blazor, it also cannot know, which routes would not map to anything (razor pages and blazor combined). Other please correct me here.
There's server-side routing and client-side routing. On the server side, the middleware pipeline runs first, handling static files and server defined routes, including the fallback route. Fallback routes are routes that don't match static file requests and have the lowest priority, so they are not preferred over other matching routes.
Server-side routing has no idea what routes are going to match on the client-side. That data model is separate. What's happening is, when no server route matches, the host page is rendered, which bootstraps the client. Now you've transitioned to client-side routing and cannot re-enter (without a change to refresh the browser)
What if I want to display a static file (.html) from wwwroot or a specfic RAZOR PAGE (.cshtml), which doesnt establlish a websocket for all those cases where the route does NOT EXIST IN ANY BLAZOR PAGE ???
That requires knowing what routes exists on the client.
Idea: I could try to add ALL POSSIBLE Blazor-routes as fallbacks and the most general fallback to some static file or Razor Page... but that seems LIKE A LOT OF DOUBLE WORK and very error prone... is there no way?
Possible using the <NotFound> component to run some JavaScript and redirect the browser to a fixed route on the server.
Edit:
Another would be to build that found all routable razor components and map them all as fallback routes to "_Host".
Something like this (untested):
// This should match wherever components are declared.
var types = typeof(Program).Assembly.GetTypes();
foreach (var type in types)
{
if (typeof(ComponentBase).IsAssignableFrom(type) && type.GetCustomAttribute<RouteAttribute>() is { } routeAttribute)
{
var route = routeAttribute.Template;
endpointRouteBuilder.MapFallbackToPage(route, "/_Host");
}
}
It partly depends on how your app is hosted. In IIS, you can add applications to any website, which are basically websites of any type you want with a "/path" added.
Currently, my company's main app is "ABCsite.com," and my Blazor app is "ABCsite.com/Blazor"

ASPNET Core 3.1 Razor Pages with virtual directory in kestrel

I have two web sites developed using Aspnet core 3.1 Razor Pages, hosted by kestrel. Example:
https://localhost:50001/*
https://localhost:50002/*
There is no problem when running in debug mode. However in production I would like to do the old IIS method where we can add a virtual directory to the URL. Example:
https://example.com/MyAppA/*
https://example.com/MyAppB/*
I knew kestrel cannot do this, but I can't use IIS as well because I need to deploy these web site in non windows environment.
May I know if it is possible for me to modify the routing in Razor Pages to add the MyAppA or MyAppB in my code?
The simplest way of doing so is to move all the pages in [solution]\Pages\* to [solution]\Pages\MyAppA\*, but I will keep this as an last option.
Thanks
How about using the PathBase middleware, please try the answer here https://stackoverflow.com/a/57494684/4076996
You can try this,
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
//this is page level so you need to add every page
options.Conventions.AddPageRoute("/index", "MyAppA");
options.Conventions.AddPageRoute("/test1", "MyAppA/test1");
});
}

How to change base url?

I am not sure the title of the question is correct, but I'll try to explain what I need.
We host multiple web applications on a single machine, so
https://localhost:8080
and
https://localhost:8081
point to different applications.
Meanwhile, API gateway maps request without dropping the URL suffix:
https://api.domain.com/service1/Home/Index
turns into
https://localhost:8080/service1/Home/Index
and
https://api.domain.com/service2/Home/Index
into
https://localhost:8081/service2/Home/Index
I would like the app's root ~ to resolve to hostUrl+suffix where suffix is a configured value.
I used this blogpost to globally prefix all the routes for controllers and pages, but now I struggle with static files.
I am able to virtually move wwwroot:
app.UseStaticFiles(new StaticFileOptions
{
RequestPath = $"/{GlobalPrefix}"
});
but <link href="~/bootstrap/css/bootstrap.css" rel="stylesheet" /> does not contain GlobalPrefix part when rendered.
So I would like to add this GlobalPrefix to whatever base URL site is hosted at. Be it a self-hosted app or in IIS.
P.S. RTFM =)
Using app.UsePathBase("/myPath")(https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.usepathbaseextensions.usepathbase?view=aspnetcore-2.2) is working in that case.
There have been changes in ASP.NET Core 2 regarding that (http://github.com/aspnet/Announcements/issues/226). Also, be aware of a strange behavior: http://github.com/aspnet/HttpAbstractions/issues/893

how work routing in "asp.net core web application"

I created a new "asp.net core web application" project. NOT MVC!.
i see in the stratup.cs, in configure method:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
question a: the url mapped directly to razor pages ('/Index' => /Pages/Index.cshtml). and there is no IController in the entire project, What the routing of MVC doing here?
quetstion b: if i want additionaly custom routing, can I do this without turn all routing to MVC methodology?
Razor pages are a feature of ASP.Net MVC, hence the dependency on certain services and middleware, but they offer a lightweight alternative to the traditional Model-Controller-View approach. A Razor view represents the View and a code-behind class represents the Model and Controller.
By convention:
/Pages/Index.cshtml routes to / or /Index
/Pages/Contact.cshtml routes to /Contact
/Pages/Store/Contact.cshtml routes to /Store/Contact
For a full answer, you should probably read the documentation.

How do I access RouteTable.Routes.MapHttpRoute?

I have a Web Forms app that I created a few months ago and I added a Web API controller. I tried to use the 'automatic' routing that I saw in a presentation recently, but all I got was a 404. Then I tried to add routing for the Web API controller in my Global.asax using MapHttpRoute, as I've seen in several tutorials. However, even after adding Imports System.Web.Http to the file, the project will not recognize RouteTable.Routes.MapHttpRoute() I have tried adding other namespaces and ensuring that I have all the necessary Nuget packages, but I still am unable to set up routing for the Web API controller. Does anyone have a recommendation of where to start?
If anyone has this same issue in C# read on.
I am also using a web forms app and set the routing through the Global.asax file. For me Intellisense was 100% correct and it would not build regardless. To get this to work I had to add the following using directives.
using System.Web.Http;
and
using System.Web.Routing;
Becareful not to use using System.Web.Http.Routing by accident. This wont work.
You should add the reference to System.Web.Http.WebHost assembly and make sure you have
using System.Web.Http;
Why ? MapHttpRoute is defined in two assemblies, in System.Web.Http:
public static System.Web.Http.Routing.IHttpRoute MapHttpRoute(
this System.Web.Http.HttpRouteCollection routes, string name, string routeTemplate)
Member of System.Web.Http.HttpRouteCollectionExtensions
and in System.Web.Http.WebHost
public static Route MapHttpRoute(
this RouteCollection routes, string name, string routeTemplate, object defaults);
First one is an Extension on HttpRouteCollection
Second one is an Extension on RouteCollection
So when you have a webforms app, your Routes are defined in a RouteCollection so you need the WebHost version.
Its because architecture allowing WebApi to be hosted also out of IIS. see Hosting WebApi
I found this thread, which indicates that IntelliSense apparently has a problem with this, but if you type something like the following, it will build and run:
RouteTable.Routes.MapHttpRoute("MyApi", "api/{controller}")
I've just created two new webforms apps (one using .NET 4, the other 4.5), did nothing more than add web api via nuget and it worked.
What version of ASP.NET is your app running in? If you're running ASP.NET WebForms 2.0/3.5 then it's not supported.
Here's a tutorial which demonstrates how to add Web API to your Web Forms app - http://www.asp.net/web-api/overview/creating-web-apis/using-web-api-with-aspnet-web-forms
I have the same case, I solved by creating the api controller, when you add the
api controller VS will load all required refrences.