I am trying to do some MVC routing, following online tutorials, but for some reason the routing is not working.
I am trying to do http://www.website.com/news/news-title
The route I am trying to do is below.
routes.MapRoute(
"News",
"{controller}/{url}",
new { controller = "News", action = "Index", url = "" }
);
Within my NewsController I have the following ActionResult.
public ActionResult Index(String url)
{
return View();
}
However, when stepping thorough the code, url is not being populated.
Thanks
== Update ==
Thank you all for your replies.
I have no amended the Route to below
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.LowercaseUrls = true;
routes.Add(new SubdomainRoute());
routes.MapRoute(
"News",
"News/{action}/{slug}",
new { controller = "News", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
This URL works: /news/index/?slug=test-news-title
But this URL does not: /news/index/test-news-title
=== Further Edit ===
It appears my subdomain route is messing with it. If i remove the subdomain route it works fine.
Thanks.
Most likely, your route is too broad. But it depends on how the rest of your routes are configured. You would need to post your entire route configuration (including area routes and attribute routing) in order to reasonably get an answer what is wrong with your route.
However, you can be more specific with this route because you know that it needs to start with /News.
routes.MapRoute(
"News",
"News/{url}",
new { controller = "News", action = "Index" }
);
Also, it probably doesn't make sense to make the URL parameter optional by providing a default value. If you remove url = "", the url parameter is required in the URL. If configured as above, if you just pass /News, it won't match this route. However, as you have it this URL will match.
Finally, make sure this route is placed in the right order. It should be placed before your default route (if you still have it).
You have set for the parameter url the empty string. you should use instead UrlParameter.Optional (or removing it at all if is mandatory):
routes.MapRoute(
"News",
"{controller}/{url}",
new { controller = "News", action = "Index", url = UrlParameter.Optional }
);
You are missing the action part in the MapRoute
routes.MapRoute(
"News",
"{controller}/{action}/{url}",
new { controller = "News", action = "Index", url = "" }
);
Hope this help
Related
If I have the following MapRoute:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
I can have an url like:
blabla.com/Home/Index/123
But what kind of MapRoute do I need to create to be able to do this:
blabla.com/Home/123 or blabla.com/Home/DEADBEEF?
I imagine it involves something along the lines of
"{controller}/{id}/{action}"
Action and id are reversed, and maybe there should be a default action. But how will the MapRoute know which controller should be treated like this?
You probably need something along these lines.
routes.MapRoute(
name: "DefaultRoute",
url: "Home/{action}",
defaults: new { controller = "Home", action = "Index" },
constraints: new { action = "[A-Za-z]*" }
);
or without an action
routes.MapRoute(
name: "DefaultRoute",
url: "Home/{id}",
defaults: new { controller = "Home", action = "Index", id = "" },
constraints: new { id = "[A-Za-z]*" }
);
You will need to make sure that the route name is different than any other routes you have setup and pay attention to the ordering of the routes as other routes that are similar can override each other. In this case make sure you would probably want this before the default route but be aware that it will override it.
As for the not having controller or even the action you can set defaults and do not need them within the route.
As for constraints you can simply add the constraints parameter to the route to set a regular expression for a certain attribute as shown above.
EDIT:
Here are some useful links for more info on routing if you need it.
http://www.dotnet-tricks.com/Tutorial/mvc/HXHK010113-Routing-in-Asp.Net-MVC-with-example.html
http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx
Advanced ASP Routing tutorials and examples
You can add a route like this:
routes.MapRoute(
"CustomRoute",
"Home/{id}",
new { controller = "Home", action = "Index", id = "" });
Make sure you place it above the default route. However this route will block all the other actions in HomeController. Since we don't have a constraint on id parameter, the framework can't possibly know if you are referring to an action or an id in your URL. Since this route comes first, it will map it to id parameter.
I am trying to write a rule to map a URL but so for I did not get the results I want. I have this rule so far:
routes.MapRoute(
"Search", // Route name
"{controller}/{action}/{product}/{page}", // URL with parameters
new { controller = "Home", action = "Search", product = UrlParameter.Optional, page = UrlParameter.Optional } // Parameter defaults
);
using this I can achieve this result so far:
localhost:8493/home/search/myproduct
localhost:8493/home/search/myproduct/2
but i want to do something like this:
localhost:8493/myproduct
so this will route to home/search/myproduct
I have tried the following but it didn't work:
routes.MapRoute(
"DirectSearch", // Route name
"{product}/{page}", // URL with parameters
new { controller = "Home", action = "Search", } // Parameter defaults
);
Is there a way to do this?
Add:
So Here i added the specific route to map to another action but it doesn't work:
routes.MapRoute(
"Tuna",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Tuna", id = UrlParameter.Optional }
);
You're close I think. This should work;
routes.MapRoute(
"Search", // Route name
"{product}/{page}", // URL with parameters
new { controller = "Home", action = "Search", product = UrlParameter.Optional, page = UrlParameter.Optional } // Parameter defaults
);
Just remember that the framework will read the route data from top to bottom and use the first one it finds that matches. So make sure the more specific routes are listed before the more general ones
Edit
Here's a link to a discussion on custom routing
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 an MVC3 site with 2 areas plus the common area. I also have a route specified for paginating lists of items. My Register_Routes method looks like so:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Paginate", // Route name
"{controller}/Paginate/{itemsPerPage}/{pageNumber}/{searchString}", // URL with parameters
new { controller = "Home", action = "Index", itemsPerPage = SiteSettings.ItemsPerPage, pageNumber = 1, searchString = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
What I've noticed (and don't understand) is if I log out from my home page, the redirect from my login page looks like
http://localhost:62695/Account/LogOn?ReturnUrl=%2fHome%2fPaginate
... and upon logging in, I end up on my home page, except with a URL of:
http://localhost:62695/Home/Paginate
I'm fairly certain at this point that I've screwed something up with the route map, but it seems right to me. What am I doing wrong?
UPDATE
per suggestion, I changed my routes to look like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Paginate", // Route name
"{controller}/Paginate/{itemsPerPage}/{pageNumber}/{searchString}", // URL with parameters
new { controller = "Home", action = "Index", searchString = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
... and the home index pages do indeed seem to work properly, but now the paginates don't:
return RedirectToAction("Paginate", new { itemsPerPage = SiteSettings.ItemsPerPage, pageNumber = 1, searchString = string.Empty });
in a Admin\HomeController yields the URL:
http://localhost:62695/Admin/Users/Paginate?itemsPerPage=25&pageNumber=1
so I'm still doing something wrong here.
UPDATE 2
OK, this is how I got it to work the way I wanted it to:
My RegisterRoutes method now looks like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
null,
"{area}/{controller}/Paginate/{itemsPerPage}/{pageNumber}/{searchString}", // URL with parameters
new {area = string.Empty, controller = "Home", action="Paginate", searchString = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{area}/{controller}/{action}/{id}", // URL with parameters
new {area = string.Empty, controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
... but this was not enough to fix the routing issues. Additionally to this, I needed to add the route to my area registrations. My AdminAreaRegistration looks like this:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
null,
"Admin/{controller}/Paginate/{itemsPerPage}/{pageNumber}/{searchString}", // URL with parameters
new { controller = "Home", action = "Paginate", searchString = UrlParameter.Optional } // Parameter defaults
);
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
This, in addition to changing to RedirectToRoute for my connections, made my URLs all pretty and working at the same time. All the answers helped to get to my goal, I +1'd everyone and chose the answer that got me closest to the path.
Routes are evaluated in the order they are registered. The redirects are being generated by the first route that you registered, especially since you declared default values for all of the segments. You might want to consider defining a more specific route
UPDATE
Use RedirectToRoute instead of RedirectToAction to get your desired URL generation
RedirectToRoute("Paginate", new { itemsPerPage = SiteSettings.ItemsPerPage, pageNumber = 1, searchString = string.Empty });
routes.MapRoute(null, // do not name your routes, it's a "magic string"
"{controller}/Paginate/{itemsPerPage}/{pageNumber}/{searchString}",
new
{
controller = "Home",
action = "Index",
searchString = UrlParameter.Optional
}
);
// instead of RedirectToAction, try RedirectToRoute, and do not use the route name
return RedirectToRoute(new
{
controller = "Home",
area = "AreaName",
itemsPerPage = SiteSettings.ItemsPerPage,
pageNumber = 1,
searchString = string.Empty,
}
);
Well, the reason you return to the URL http://localhost:62695/Home/Paginate is because when you log in you return to the URL specified, namely the ?ReturnUrl=%2fHome%2fPaginate part of http://localhost:62695/Account/LogOn?ReturnUrl=%2fHome%2fPaginate. Is that not the URL of your home page? You never specified.
It could be that the first definition takes precedence also, not sure where I heard that, so maybe if you put the default definition first it will grab that.
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
);