I have created a web application using ASP.NET Core 2.1 MVC.
And currently i am having an issue with routing when the application is published.
The url format where the application will be published is this : https://hostername.com/{some_parameter}
All the generated url-s from my application should be "attached" to the above mentioned url.
So i need to have a routing like this :
https://hostername.com/{some_parameter}/{controller}/{action}/{id}
Some examples :
- https://hostername.com/ApplicationName/Home/Profile
- https://hostername.com/ApplicationName/Home/Settings
- https://hostername.com/ApplicationName/FAQ etc...
My solution for this after reading couple of questions/solutions on stackoverflow :
Changed the default route to
routes.MapRoute(
name: "default",
template: $"{{parameter={settings.PrefixURL}}}/{{controller=Home}}/{{action=Index}}/{{id?}}");
where settings.PrefixURL => it's the some_parameter and it's value it's dynamic.
Problem i am facing =>
Doubled parameters in url, for example :
- https://hostername.com/ApplicationName/Home/Home/Profile
- https://hostername.com/ApplicationName/ApplicationName/FAQ
When tested locally that configuration of default routing worked perfectly, but after publishing the routing still works but the url is wrong.
What could be causing the issue?
Would creating Areas solve the routing to that kind of url?
Thank you.
What did the work for me was editing the path on web.config file and leaving the rest of soultion untouched.
From path="*" to path="/ApplicationName" where ApplicationName is the desired routing parameter.
Related
So it's my first time setting up an netcore MVC based application. I've used MVC 4 in the past on plain old asp.net.
So i'm having issues with my routing. My application is an single page application (spa) that is accessible from the home controller on the index action. I can access this controller method fine, and my defaults are set so that this is navigated to at route: /.
I also have a second controller for authentication called AccountController. This controller's methods take and return JSON, rather then views. I can also access the methods on this controller from my application.
The issue i'm having lies in my next controller, which is the start of my API.
As such, i've put it in a folder called api inside my controllers folder. However, no matter what i try, i cannot seem to get the methods on the controller accessible. I have also tried moving it out of the api folder and just having in the route of the controllers folder.
The routing deffinition
app.UseMvc(routes =>
{
routes.MapRoute(
name: "api",
template: "api/{controller=Core}/{id?}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
I've tried adding and removing the api definition, removing the api part, and adding a template for actions aswel, all to no effect.
The troublesome controller
public class CoreController : Controller
{
[HttpGet]
public JsonResult Get()
{
return Json("Dev");
}
}
I've tried adding [Route(~routing here~)] annotations to this controller and its methods with no success either.
Folder structure
I should also mention that i've tried plenty of URL's to access this controller on:
/api/Core/
/Core/
/api/Core/Get
I've been wracking my brain for the best part of a day trying to get this sorted and i know i'm missing something obvious, i just can't for the life of me work out what it is.
Edit:
I've added a cut-down sample of my project to github at: https://github.com/lexwebb/aspnet-test if anyone would like a complete example
Edit 2
It appears that my example works, i'm going to add things in to see what breaks it
AFAIK, default route requires the {action} using as well.
Instead of "api" default routing, you may to use the following configuration for such type of controllers (RESTFul controller):
[Route("api/[controller]")]
public class CoreController : Controller
{
[HttpGet]
public JsonResult Get()
{
return Json("Dev");
}
}
I found this Routing is ASP.NET Core article useful in the past.
So as it turns out, i had made a mistake in a totally unrelated place. I had renamed my project half way through the beginning stage of development, after i had build scripts in place. This led to the the wrong dll being referenced on the server when the code was ran, a version that had all of my routing EXCEPT the new one, of course.
With the help of several online tutorials, like this one, I am still struggling to add a Web API service to an existing Asp site, that is not MVC.
I added to the project a new item of type Web API Controller Class(v2.1), named it something like AbcController.cs, and VS2015 asked me to put it in the App_Code directory. The default code has handlers for Get, Put etc. Sounded to me like I am on the right track.
I added a default route in Global.asax.cs like in the tutorial:
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
This got built after adding a reference to System.Web.Http.Webhost which was not mentioned in the tutorial. Sounded like I was still on the right track.
However, it doesn't work. I run the site in debug and this gives me a 404 Not Found:
http://localhost:54905/api/abc
I tried to run this on the production server with IIS7, of course as a second test web site to not interfere with the version that is in production. However, I ran into the error that the Microsoft.Web.Infrastructure dll could not be found. To fix this, I should install MVC packages, which I don't like for just an experiment.
My questions are:
do I get it right that the URL is in lower case, i.e., not .../api/Abc ?
does this kind of routing work in the debugger?
am I essentially turning the web site into an MVC web site?
is this really the simplest way to add a "REST" service to an existing web site? I only need to implement the POST, read and return some JSON data, and do not need arguments in the URL
I want to display a default status page for my web api project (where instead some IIS message is displayed when I start the project). However it seems like I cannot create views in web api (there is no support for ActionResult).
In addition to a status page I will also use this information to create an api documentation page.
How can I achieve displaying html pages in this situation ?
If your default status page is static html, you don't have to use MVC. Just tell WebApi in your Startup.cs that you want to support static resources:
app.UseFileServer();
For creating an API documentation, maybe you could write that file on startup dynamically?
You can create regular controllers and views in a webAPI project the same as any MVC project. Just create a normal controller that does not inherit from ApiController. In your startup.cs make sure to configure at least a default route.
configuration.Routes.MapHttpRoute(
name: "someName",
routeTemplate: "{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Right click and select Add, then you should see controller at the top. Select one of the mvc controllers.
I received a prototype application built with Asp.Net MVC4. It is currently replacing the default controller factory with a custom one using NInject, ServiceLocator and all.
The problem is that by replacing the default controller factory, the requests to JS files are being treated as if it was a legit request for a controller and an action.
So, looking at the default template create by Visual Studio, route configuration looks like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
After looking that, I'm asking myself: How come a request to "/Scripts/jquery.js" does not get interpreted by Asp.Net MVC? I mean, why doesn't it think "Script" is a controller and "jquery.js" is an action?
Because the project works if I disable the controller factory override, I can only assume that the default factory is the responsible for that kind of check. And that would mean that a "/Scripts/jquery.js" are indeed passed to the controller factory which is something I didn't really know.
Could anyone shed some light on that?
What kind of treatment should one do when overriding the controller factory to avoid such problems?
It's not because of how MVC handles the request to jquery.js it's because of the way IIS handles the request to jquery.js. IIS assumes that resources such as .js, .jpg, etc, are all static resources, and thus doesn't need to pass them through the ASP.NET engine. In order to to prevent this from occurring you can add a line to the web.config for a path that you want IIS to leave alone.
<system.webserver>
<handlers>
<add name="scripts" path="/Scripts/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
</system.webserver>
Adding something like that should allow your JS files to be served via ASP.NET and not directly through IIS.
After a little bit more of research I found the following quote from Steven Sanderson's book:
However, the routing system still does check the file system to see if an incoming URL happens to match a file or disk, and if so, routing ignores the request (bypassing any route entries that the URL might also match) so that the file will be served directly. This is very convenient for static files, such as images, CSS, and JavaScript files. You can keep them in your project (e.g., in your /Content or /Script folders), and then reference and serve them directly, just as if you were not using routing at all. Since the file genuinely exists on disk, that takes priority over your routing configuration.
If, instead, you want your routing configuration to take priority over files on disk, you can set the RouteCollection’s RouteExistingFiles property to true. (It’s false by default.)
That was something very interesting to learn and led me to the actual problem. A much simpler one. As it happened, the pertinent scripts were not present on the folder. At least not the ones with the exact same version requested on the view. That was the responsible for Asp.Net MVC thinking it was a controller/action request.
Reference: http://forums.asp.net/t/1536510.aspx/1
check that use "~/" before your Links or Scripts like :
src="~/assets/js/main.js"
I have a Url like this
http://localhost:4737/Site/listing/NH/Plaistow/2831516
and I want it to reroute to
http://localhost:4737/Site/listing.aspx
I was reading how to do this for Web Forms here
https://web.archive.org/web/20211020111718/https://www.4guysfromrolla.com/articles/012710-1.aspx
Here's what my route looks like.
routes.MapRoute(
"FriendlyUrl",
"Site/listing/{state}/{town}/{mlsnumber}",
"~/Site/listing.aspx");
In my listing page I plan on accessing the following variables
Page.RouteData.Values["state"]
Page.RouteData.Values["town"]
Page.RouteData.Values["mlsnumber"]
But when I navigate to http://localhost:4737/Site/listing/NH/Plaistow/2831516,
I just get a HTTP 404 error.
I know how to get this working with MVC, but this is a fairly large application, all written with web forms, so rewriting isn't feasible.
Any ideas on how to troubleshoot this would be helpful.
Thanks !
Here is the working code. Thank you to mrchief for helping me resolve this.
routes.MapPageRoute(
"FriendlyUrl",
"listing/{state}/{town}/{mlsnumber}",
"~/listing.aspx");
Yore doing it the other way. If you're using WebForms, you need to implement UrlRoutingModule as shown here: https://web.archive.org/web/20201205221404/https://www.4guysfromrolla.com/articles/051309-1.aspx
The Routing Rules were designed for use in ASP.Net MVC applications where you redirect a Url to its appropriate Controller (Page in WebForms) with action params (query params in WebFroms parlance).