I am learning MVC and I need to understand why it doesn't work the way it should.
Here is my routing :
public static void RegisterRoutes(RouteCollection routes)
{
// Note: Change the URL to "{controller}.mvc/{action}/{id}" to enable
// automatic support on IIS6 and IIS7 classic mode
//http://localhost/store/category/subcategory/product
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Category", // Route name
"store/{category}/{subcategory}", // URL with parameters
new
{
controller = "Catalog",
action = "Index",
category = "Featured Items",
subcategory = "All Items"
}
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }, // Parameter defaults
new { controller = #"[^\.]*" } // Parameter constraints
);
}
The way I understand routing I should see the following url when I start the web app :
http:/localhost/store/
What I get is the second route....
Furthermore if I change the second route to "home/{action}/{id} it doesn't catch any routes.
Could you help me understand this please..Thanks
Routes do not specify default URL; the default URL is handled by your app. Routing specifies that when it sees http://localhost/store/bikes/mountain, it will use the catalog controller. But that doesn't specify the default URL; you have to enter that in the project properties.
I would recommend not changing the second one because unless you are creating groupings for all of your controllers, it's best to have the default as it is so you can catch all URL's. Your change to the second one would require the url to be:
http://localhost/home/home/index to match the HomeController's index action, whereas the default setup catches http://localhost/home/index...
Does that make sense?
Try this: http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx
Related
This is related my question which i asked in this link correct me on url routing in mvc
Now i came with another problem, so i thought i will ask it as new question.
Now i have following routes in my global.asax file
routes.MapRoute(
"Custom", // Route name
"{action}/{id}", // URL with parameters
new { controller = "Authentication", action = "BigClientLogin", id = UrlParameter.Optional } // Parameter defaults
);
and
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Authentication", action = "BigClientLogin", id = UrlParameter.Optional } // Parameter defaults
);
Now what happens is when i run my solution the URL i am getting is http://localhost:65423/Login this is what i need for my Login Page that is OK. But when i login in as user i am getting "The resource cannot be found" error.
when i checked it i can see that my URL is now changed to http://localhost:65423/Admin/Dashboard
So i think this causing the issue. So this looks the problem related to my global.asax routing.
Can anyone help me to find out what i did wrong.
You have 2 routes with completely optional segments. The issue is that there is no way for the routing framework to differentiate between them.
The only way you can make it work with your existing routes is to specify them explicitly by name (such as when using #Html.RouteLink or #Html.RouteUrl).
#Html.RouteLink("Custom Link 1", "Custom", new { action = "BigClientLogin" })
#Html.RouteLink("Custom Link 2", "Custom", new { action = "Action2" })
#Html.RouteLink("Home Page", "Default", new { controller = "Home", action = "Index" })
#Html.RouteLink("About", "Default", new { controller = "Home", action = "About" })
Doing it that way will function, but is not normal. Typically, there is only one route configured with all defaults for the controller, action, and id and the rest have some explicitly declared segments and/or constraints (segments being preferable).
routes.MapRoute(
"Custom", // Route name
"Custom/{action}/{id}", // URL with parameters
new { controller = "Authentication", action = "BigClientLogin", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Authentication", action = "BigClientLogin", id = UrlParameter.Optional } // Parameter defaults
);
The first route will now only match when the URL starts with /Custom/. If it does not start with custom, it will match the default route.
The trick is to ensure that the routes are listed in the right order and that they only match the URL in specific cases, letting them pass on to the next route in the list if the case is not correct.
It happens because of 2 things.
1st the sequence of Your route
2nd your defaults
So if you end up on 'admin/dashboard' that's not a default, guess you've just put it in your studio to start there?
To get to http://localhost:65423/Login you'll need an action on Your AuthenticationController called 'Login' but it looks like the one You have configured is 'BicClientLogin' so You won't be taken to login unless you specify it, and at that time it has to exist.
To Help You further we need to know what controllers You have and what actions there exists, plus if security is part of your solution and if in case, what is is set to use.
I have a domain "http://www.abc.com". I have deployed an ASP.net MVC4 app on this domain. I have also configured a default route in RouteConfig.cs as shown below
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "MyApp", action = "Home", id = UrlParameter.Optional }
);
The above mapping ensures that anyone attempting to visit "http://www.abc.com" is automatically shown the page for "http://www.abc.com/MyApp/Home"
Everything works as expected but the address bar in the browser shows "http://www.abc.com" instead of "http://www.abc.com/MyApp/Home". Is there any way to force the browser to show the complete URL including the controller and Action?
One option would be to set your default route to a new controller, maybe called BaseController with an action Root:
public class BaseController : Controller
{
public ActionResult Root()
{
return RedirectToAction("Home","MyApp");
}
}
and modify your RouteConfig to point to that for root requests:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Base", action = "Root", id = UrlParameter.Optional }
);
You'll need to do some kind of url rewriting. Probably the quickest way is to add a RewritePath call to your BeginRequest in Global.asax. In your case it'd be something like this:
void Application_BeginRequest(Object sender, EventArgs e)
{
string originalPath = HttpContext.Current.Request.Path.ToLower();
if (originalPath == "/") //Or whatever is equal to the blank path
Context.RewritePath("/MyApp/Home");
}
An improvement would be to dynamically pull the url from the route table for the replacement. Or you could use Microsoft URL Rewrite, but that's more complicated IMO.
Just remove the default parameters, it's been answered here:
How to force MVC to route to Home/Index instead of root?
I have a request controller that is getting out of hand, and I want to divide the actions on several controllers while maintaining a clean URL. I'm trying to experiment with routing, but without success. I've read some examples and tutorials on routing, but, though I understand the examples, nothing seems to apply to my case, and I feel non the wiser. What I want is for the URL Requests/Approval to be handled on my ApprovalController instead of my RequestController, so I wrote the following.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Approval",
"Request/{controller}/{action}",
new { controller = "Approval", action="Index", id = "" }
);
}
But it's not working. Why? I have a folder in the my Views called Approval, and in there I have a file called Index.cshtml. How should I code the MapRoute?
Edit
I added all the routes I've got
You need to swap the two MapRoute statements, like so:
routes.MapRoute(
"Approval",
"Request/Approval/{action}",
new { controller = "Approval", action="Index", id = "" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
The reason it is currently not working is because the first statement ('Default' route name) is getting matched before the second one is even evaluated.
In addition (as noted in my above example,) you need to remove '{controller}' in the Approval route and replace with 'Approval'... unless you specifically want the URL /Request/{ANY controller}/{action} to go through, which I doubt. From your question it seems you only want /Request/Approval/ to go to your Approval controller.
Don't forget to keep the Default route at the bottom, so as to match your other controllers and actions. It serves as a catch-all should no other matches exist.
The order you map your routes matters. Move the second route before the default route.
You will still have a problem though, as any thing /request/something will look for the SomethingContoller. To fix this, change your route to this:
routes.MapRoute(
"Approval",
"Request/Approval/{action}",
new { controller = "Approval", action="Index", id = "" }
);
I have a psychical path: Home/signUp.aspx
and Controller/HomeController.cs (related to Views/home/index.aspx)
My routing is configured in the global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.IgnoreRoute("{resource}.ashx/{*pathInfo}");
//settings - manage toolbars
routes.MapRoute("SettingsManageToolbars", "home/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
"Default",
// Route name
"toolbar/apps/{controller}/{action}/{id}",
// URL with parameters
new { controller = "Home", action = "Index", id = "" }
// Parameter defaults
);
}
When I surf to home\signup.aspx
I get a text page with "directory content"
How can I fix this routing?
By default, routing does not handle requests that map to an existing physical file on the Web server. Routing does not handle the request even if it matches a defined pattern, such as {controller}/{action}/{id}.
If you want routing to handle all requests, even requests that point to files, you can override the default behavior by setting the RouteExistingFiles property of the RouteCollection object to true. When you set this value to true, all requests that match a defined pattern are handled by routing.
http://msdn.microsoft.com/en-us/library/cc668201.aspx#scenarios_when_routing_is_not_applied
Why is your home controller an aspx file? Try making it a HomeController.cs!
I'd suggest deleting your current controller and adding another via the context menu (right-click, Add)
I'm writing an MVC3 application that will need to make use of URL rewriting in the form of http://[server]/[City]-[State]/[some term]/ .
As I understand it, MVC3 contains a routing engine that uses {controler}/{action}/{id} which is defined in the Global.asax file:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Traditionally (in a non-MVC app), I would use some URL rewriting flavor to decode a url such as http://www.myserver.com/City-State/somesearch/ to querystring parameters that look something like this:
http://www.myserver.com/city=City&state=State&query=somesearch
Keep in mind that this request would be coming from http://www.myserver.com/Home
Can this can be accomplished without having to specify a controller... something like this:
routes.MapRoute(
"Results",
"{city}-{state}/{searchTerm}",
new { controller = "Results", action = "Search" }
);
... or is it really best to have the controller listed?
How do you handle this in an MVC3 environment?
Thanks.
URL rewriting in asp.net MVC3:-
you can write code for url rewriting in Global.asax file :-
//Default url
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"",
new { controller = "Home", action = "Index", id = "" }
);
//others url rewriting you want
RouteTable.Routes.MapRoute(null, "Search/{City_State}/{ID}", new { controller = "Home", action = "Search" });
Check out these two answers:
ASP.NET MVC Routes: How to define custom route
Defining custom URL routes in ASP.Net MVC
Summary:
Specify custom routes before the default one.
Define specific routes before general as they may match both.
Default values are optional.
Specify default Controller and Action in the default parameter object.
You can do this by registering route in Global.asax file, but order to register the Route is important you must be register first Old route then new one.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// for Old url
routes.MapRoute(
"Results",
"{city}-{state}/{searchTerm}",
new { controller = "Results", action = "Search" }
);
// For Default Url
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);