I have an annoying problem with folder names and routes in ASP .NET Mvc 5,
This is the default routes I'm using:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Site", action = "Index", id = UrlParameter.Optional }
);
And I'm also using a custom view engine to map views to the root folder instead of ~/Views so I can have HTML/CSS/JS files organized in a way my team can handle.
The problem is: When I call /Backoffice/Index it goes normally and executes action Index in controller Backoffice, all fine, but when we call /Backoffice, I expected it to presume the action index (by the route configuration), but instead, IIS seems to believe I'm trying to access the folder /Backoffice and gives me a 404 error instead of executing Backoffice::Index().
How can I configure IIS to behave in the intended way in this case? Or, is it really the only best way to keep views in a specific folder?
I did some research and used info from the comments and answers here and got to learn something about how MVC routes work and how IIS handles that.
When we set
routes.RouteExistingFiles = true;
The MVC runtime will ignore every file in the folder and start using the routes and URIs solely to look for controllers and actions, this means by calling /SomeContent it will search for a controller named Somefolder instead of a folder. Then we can configure to serve static content by telling MVC runtime to ignore some specific URI formats:
routes.IgnoreRoute("SomeContent/CSS/{filename}.min.css");
routes.IgnoreRoute("SomeContent/JS/{filename}.min.js");
This causes MVC to ignore URIs that match this pattern and leave it for IIS to resolve what to do with it, then IIS will look out on Web.Config rather there are configurations set to serve this kind of static content and what handler to use and proceeed as usual.
Using this configuration can bring MVC to a whole new level of control where you explicitly define which URI patterns serve static content, everything else explicitly calls an action on a controller, all URIs get to be firstly processed by MVC runtime. I sure wish someone correct me in this last statement if I get it wrong.
MVC routes certain actions based on whether they exist on disk. If you have a folder /BackOffice at the root level, then this appears to be a complication that MVC is going to have issues working around (I knew files were directly routed if they existed; I didn't realize folders were something the framework checked too). Consider renaming the folder or the controller to something else so you don't have this naming conflict. That is a problem with "by convention" approaches....
Related
I've created an application that mixes mvc and web forms.
I have a question about how the routing is working when I mix these two.
This is just for testing purpose only.
I have a controller called Family and it has an action method called Index.
At the same time I have a folder called family which contains an aspx page called Index.
When I go to localhost/family/Index I get the controller action method view
and when I go to localhost/family/Index.aspx I get the webform page.
How does this work? How does it know whether to look for Family controller or Family the folder?
When you call localhost/family/Index IIS looking for the route in route config table that defined from RouteConfig.cs in App_Start and then you can see the Index ActionResult from FamilyController but when you looking for localhost/family/Index.aspx IIS looking for a file that name is Index.aspx in the family folder.(of course at the first, IIS looking in route config then looking for file and folders.)
Problem
I have two controllers: RequestsController and ServicesController. Both contain Index actions.
When I browse to /Requests, it automatically runs the Index action, but for /Services or /Services/, it gives an HTTP 404 without even running the Index action.
Background
The route configuration is stock. The project also contains various classes under a top-level directory called Services:
Troubleshooting
The problem seems to be related to some sort of clash in naming between ServicesController and the top-level Services folder.
I can still access /Services/Index without a problem.
Debugging confirms that the Index method is being run for Requests but not Services when I don't specify the action name in the URL.
Renaming or removing the top-level Services folder causes the problem to stop happening.
I see. That's a common issue when you have a controller with the same name as a folder inside the root directory. Assuming that none of the files inside the Services folder are mapped by the StaticFilesHandler I think you can simply tell the routing system to map all "services" routes to the ServicesController by setting the RouteExistingFiles to true...
routes.RouteExistingFiles = true;
Update
I completely ignore the Content folder. You will need to prevent requests to the "Content" folder (or any other folder containing static files such as the Scripts folder) from going through the routing pipeline by explicitly specifying it BEFORE your routing-mapping logic...
routes.IgnoreRoute("FOLDER_NAME/{*pathInfo}");
I have followed Maarten Balliauw's post on domain routing. I had been able route to controller's for different sub-domains. But I don't know how to route to a virtual directory. As you see this is a sample example for routing to usual mvc controllers,
routes.Add("DomainRoute", new DomainRoute(
"home.example.com", // Domain with parameters
"{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
));
As my blog resides on Virtual Directory I need to add the route to this virtual directory named "~/blog"
I have tried code like this with no good result,
routes.Add("DomainRoute", new DomainRoute(
"blog.domain.com", // Domain with parameters
"blog", // URL with parameters
new { controller = "blog" } // Parameter defaults
));
If anyone can bring some light into this it will be amazing.
You could try to make the blog an MVC Area of your main web application. You create a new Area called blog. This creates a Folder called "Areas/blog" in your main webroot. You can then turn the 'blog' folder into a virtual directory pointing to your blog application.
I did this in a recent web project for my admin backend. I used this blog post and it worked great. Very simple and keeps your application nice and clean.
http://bob.archer.net/content/aspnet-mvc3-areas-separate-projects
When you are actually inside the 'blog' area your actionlinks and everything works like normal. You only need to add "Area = 'blog'" to your links that move you from area to area.
Once you create the blog area take a look at the routes file it creates. I hope that makes sense.
The implication here is that the virtual folder is completely distinct from the MVC application it's within -- if that's the case, do you need to use the MVC routing at all, since you don't need any of the MVC resources to begin with? It would probably be easier just to configure the subdomain to point at the appropriate folder within IIS, and bypass MVC's routing altogether.
We liked the approach to have all the pages regarding support - for example - under http://www.company.com/support. After migrating to ASP.NET MVC 3 and trying this we can run every type of page but not inside the same folder.
Is there any workaround for this?
Thanks.
If you need to mix MVC pages and non-MVC pages in the same folder, here's some tips:
Remove the default route "/{controller}/{action}/{id}" and make routes for each MVC page. That way any request that isn't caught by a route falls through to the "old" request handling.
A return View(); method call in a controller looks for a view in a folder named as the controller in the Views folder, so specify the name of the view, e.g. return View("/support/index");.
Note that the MVC views doesn't actually have to be in the folder support, you can put them anywhere you like, it's the routes that determine which URLs are handled by MVC.
I am using System.Web.Routing in the Asp.Net Webform Application. I wrote the following route in the global.asax
routes.RouteExistingFiles = true; // I made true/false both, but none works
routes.Add("competition", new Route
(
"Test",
new CustomRouteHandler("~/Test/WebForm1.aspx")
));
And the directory structure is the following:-
Application
|
|--- Test (Folder)
|--- Webform1.aspx
When I write in the browser http://localhost:xxxx/Test/ (using Casini), the request is handle in the traditional manner not through the routes, and, it gives me the "Directory Listing -- /test/" page.
Could you please help me out?
I had the same problem, and I chose the pragmatic solution that the file that should handle the default path is called Default.aspx
routes.Add("competition", new Route ( "Test", new CustomRouteHandler("~/Test/Default.aspx") ));
Are you using Routing straight out the box for WebForms, I have just implemented this for "WebForms" specifically, since there is some things to be aware of:
http://haacked.com/archive/2008/03/11/using-routing-with-webforms.aspx
HTH
Update:
Using the implementation in the link still produces the same error, since the actual folder exists.
I would think that since the folder exists, it would be served (in some cases listing the folder contents may be desired)
Maybe taking a different approach would be better for instance, if the pages all point to specific extranet login pages maybe an extra descriptive folder would work, eg: /Extranets/Test/ ?