MVC 4 Web Api Routing - Use relative path for routing URL - asp.net-mvc-4

Problem:
I am trying to call the ApiController from localhost:xxxx/Home/TestPage and get a 404 that the Requested URL: /Home/api/Test cannot be found.
If I make this call from the Index.cshtml page it works fine and I can navigate to localhost:xxxx/api/Test and see the desired JSON. I've tried adding ~/ to my MapHttpRoute routeTemplate but that throws an exception.
Question:
How do I remove /Home from the URL request?
Another example would be if I am on the page localhost:xxxx/People/TestPage and I want to hit multiple URIs such as localhost:xxxx/api/Hobbies, localhost:xxx/api/Pets and locahost:xxx/api/Vehicles. How would I set up the custom routing to handle this? As of right now with the default routes, I get the error that it can't find /People/api/Hobbies and so forth.
SOLUTION (Possibly):
I created a custom MapHttpRoute with the routeTemplate: "{page}/api/{controller}/{id}" and it works but I don't completely understand WHY and if this is good practice or not.

Home is your default HTTP controller. Home/api/Test is not a valid Web API controller route unless you have created custom routes. The out of the box default web api route is api/{controller}/{id}. So, if you had an API controller called home, it's URL would be localhost/api/home/id

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"

Swagger ignoring controller route path for one action

I have a little problem with Swagger: I created a new action in my controller but when starting the web server I notice Swagger completely ignores the route of the controller. Instead of having "api/users/login" route, I just have "/login".
Screen from my code
You have specified the route as
[HttpPost("/login")]
It should be
[HttpPost("login")]
When you start the path with a slash, you override the parent route.
You can check my deep dive article for attribute routing for more info: https://joonasw.net/view/attribute-routing-cheat-sheet-for-aspnet-core

Laravel 5 - web and API Route conflict

In one of my website in laravel. I facing error 419 when i called login api below my search web route
Route::get('/{address_1}/{address_2?}/{address_3?}/{address_4?}');
Route::post('/{address_1}/{address_2?}/{address_3?}/{address_4?}');
And Below Api Route
Route::post('login', 'Auth\PassportController#login');
Route::post('register', 'Auth\PassportController#register');
In Laravel, a 419 HTTP error code is usually a sign that you are missing a CSRF token.
If the 'API' routes:
Route::post('login', 'Auth\PassportController#login');
Route::post('register', 'Auth\PassportController#register');
Are in your web.php file then this is likely because the RouteServiceProvider wraps the routes in your web.php file inside the web middleware which has the CSRF middleware enabled.
If this is the case, you will either need to include a CSRF token in your POST request, move these routes to the api.php routes file, or add the register endpoint to the $excludes array of the VerifyCsrf middleware.
update
Actually, your search routes are going to cause a lot of grief.
Given the fact that they can match any URL with one to four segments, your API routes are getting swallowed by these.
What you will need to do is alter your RouteServiceProvider to register web routes last and then put your search routes last.
This way, your pre defined routes will be registered before your “catch-all” search routes.

How to redirect to /Account/Login when calling an Action Method with Authorize attribute in ASP.NET Core

I have a Home Controller marked with Authorize attribute that contains an Index action method. I also have an Account controller with Login method. When I access /Home/Index, I only see a blank page, I was expecting it to redirect to /Account/Login. The book I am reading states that by default, it redirects to /Account/Login but it does not redirect there (the URL on browser still the same).
I tried this from an empty ASP.NET Core project, adding in what I think I only need for testing this out. Do I need to add something else? I tried the default ASP.NET Core Application with Individual User Accounts and it redirects to /Account/Login but I cannot see anywhere that this was explicitly set up so I am not sure why its working for the default sample project and not on my initially empty project.
This stuff is all handled by ASP.NET Core Identity in the project template. You can find more details about how that's setup here: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity?tabs=vs0.
It's the call to UseIdentity on the IApplicationBuilder interface that sets up the redirect for you.

MVC route for javascript logger

I have problems to post back log entries from my MVC view to my server using jsnlog.js. It works fine from my "home/index" view when my site is accessed directly on the root url "\". In other views, when jsnlog.js tries to send data to url "jsnlog.logger" it seems that the url is changed into "customer/jsnlog.logger" where customer is the current controller name.
This request ends up in a Http Status 404.
Can someone please give me an advise how to avoid the controller name to be inserted into the MVC route or if you have any other idea on how to solve this. Thanks!