I have created a controller with an Index action. All of my other Actions return the views just fine...but for some reason I have to specify the full url to have the Index view return. It's almost like my Routes aren't working correctly.
For instance, to go to the properties page, you have to go to /Properties/Index instead of just /Properties/. My routes are as follows. Any help would be greatly appreciated!
routes.MapRoute(
name: "Index",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
For security reasons in ASP.NET in general, you can't have a "Properties" path. C# projects all come with a Properties folder by default and ASP will ignore it when accessed directly to prevent file access to it.
Related
I have an issue in Routing in MFA where link like
Project_Name\Controller\Index is working, whereas
Project_Name\Controller\ is not working
This is happening for only some controllers after being deployed in a server.
I am getting the following error:
403 - Forbidden: Access is denied.You do not have permission to view this directory or page using the credentials that you supplied.
Is there any further configuration values that needs to be considered?
In RouteConfig we define the route path like this
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
So the controller you are using may have Index action method and the URL works.
But if your controller does not contain Index method or it is having parameters then it will not work.
This is a possible solution that you might create an action method named Index in all those controllers.
for more, you need to share some more details.
I have been trying to give options to users like Facebook to add their company name in the URL:
http://localhost:50753/MyCompany/Login
I have tried different URLs, but it didn't work.
routes.MapRoute(
name: "Default",
url: "{companyName}/{controller}/{action}",
defaults: new { controller = "Login", action = "Index"}
);
routes.MapRoute(
name: "Login",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
Now when I add this route to get it work, all of my AJAX requests start fails and those that succeed represent HTML rather than JSON. What I have noticed is that because of this route, my page gets reload again.
Can someone help me figure out how can it be done using MVC routing (if it's possible, or if I'm thinking in the wrong way)?
The problem you are having is due to the fact that both of these routes will match all URLs that have 1, 2, or 3 segments defined (because the controller and action have default values). Since routes are executed in order from the top route to the bottom route, your top route will always match and your bottom route never will match (except for the home page).
Since the top route always matches, URLs that assume that the first segment is the controller and the second segment is the action will fail because you are putting these values into the companyName and controller route keys, respectively.
For this to work as you expect, you need to make a route constraint that is aware of all of the company names.
routes.MapRoute(
name: "Default",
url: "{companyName}/{controller}/{action}",
defaults: new { controller = "Login", action = "Index"},
constraints: new { companyName = "Company1|Comany2|Company3" }
);
Note that you could implement IRouteConstraint so you could pull the values to match from a cached database model instead of hard-coding them into the configuration. See this post to learn how to create a custom route constraint.
Or, as Andy mentioned, you can make the match unique by specifying 1 or more segments of the URL explicitly.
url: "{companyName}/Login"
The idea is there must be some way to make the first route you defined not match in certain cases.
Alternatively, you could implement RouteBase, but you would only need to if you require much more control over the matching process than this simple scenario.
The problem is there is no way to distinguish between your two routes. For example /a/b/c could be the Default route with company = a, controller = b, action = c or it could be the Login route with controller = a, action = b, id = c.
To solve this you'll need to design your routes, including the ones for AJAX, so that there is no way two routes could have the same URL. In your example you could just drop the /{id} from the login route as it isn't needed. Also specify the URL more specifically and put it before the default. This would give you something like
routes.MapRoute(
name: "Login",
url: "{companyName}/Login",
defaults: new { controller = "Login", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{companyName}/{controller}/{action}",
defaults: new { controller = "Login", action = "Index"}
);
In this case both /MyCompany/Login and /MyCompany/Login/Index would go to the login page. However MyCompany/Home/Index would go to controller = Home, action = Index.
Personally, I tend to remove the default route altogether so I can specify the URLs I want rather than have them all as /controller/action. That gives you more control but does mean specifying each route individually.
I created an MVCApplication and it works in a directory on my server like this:
http://www.mywebsite.com/MyApp/
When I use RedirectToAction like this;
return RedirectToAction("Index", "Home");
It goes to;
http://www.mywebsite.com/Home/Index
But I want to redirect to;
http://www.mywebsite.com/MyApp/Home/Index);
How can I resolve it?
Edit---
My routeconfig is like this;
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
These redirects follow your route configuration. The default route is {siteUrl}/{controller}/{action}, which is why when you give it the "Index" action and the "Home" controller, you get the URL you're seeing.
You need to specify a new route similar to this:
MapRoute("CustomRoute", "MyApp/{controller}/{action}";
You can then redirect to it like this:
RedirectToRoute("CustomRoute", new {Controller = "Home", Action = "Index" });
EDIT to clarify for the comments -
It is also possible to solve this using IIS to make MyApp an application. This is the right solution only if MyApp is the only value you ever want at the beginning of your route for this site. If, for example, you sometimes need MyApp/{controller}/{action} and other times you need OtherSubfolder/{controller}/{action}, you need to use the routes as I have outlined above (or use areas) instead of just updating IIS.
I am assuming you want the solution using MVC, so that is what is here, but you should also consider the IIS application if that's the right solution for you.
So I am creating a site with two bindings
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
name: "DefaultAdmin",
url: "Admin/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
The idea is I want to have EndUsers to access the normal pages (/account/login etc etc ) but have a admin only portion of the site (with a different layout) for admin users.
The question is kinda two fold :-
In terms of controllers it looks like MVC just looks in the Controllers folder, is there a way to seperate out AdminControllers and Regular controllers to keep things organised?
I would like to have a separate "master view" appear for the admin than the regular, currently I'm just using _layout.cshtml from _start.cshtml but I'd like to be able to use _layout.cshtml and _adminLayout.cshtml without prefixing every view with the name of the view (if not then I can live with this one easily enough).
Any help would be apprechited.
You can place controllers anywhere in the assembly as long as they are derived from System.Web.Mvc.Controller class they will be identified by the routing logic.
You could look at "Areas" in MVC to help out with your specific need.
It sounds like Areas in MVC is what you are looking for.
Have an MVC 2 app with default route:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
This works great for everything we have except for one controller. When we browse to the url http://myserver/ThisOneController it doesn't fire the Index action and gives a 403.14 forbidden error. If I surf to http://myserver/ThisOneController/Index it works fine! Every other controller shows the expected behaviour.
The controller in question has an Index action method defined and viewing the folder in IIS seems to show no differences between that and other folders. It works in our production box but not on our test boxes...for the life of me, I can't find any differences between those boxes.
Any ideas?
Add Glimpse to your project and check what route is being used. You can then find out if the problem is in your MVC app or the environment.
This is expected behavior.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
The above route means, you expect a controller/action/id, and the default (when nothing is provided) is root/Home/Index/. So any other controller with url like root/diffController/ is not matched, since you are providing a controller, but no action.