default routing not working - c#

In my MVC application, I have following route configuration,
routes.MapRoute(
name: "ProductRoute",
url: "{productName}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Now if i give some thing like this, localhost:56789/prd1/Home/Index
The first routing is working.
However if i directly access localhost:56789/Home/Index or any other controller action, like localhost:56789/Account/Login the routing is not working.
Is it because I have a {productName} defined?
For testing purpose how can I add few products like prd1, prd2 along with routing?

Routes are matched against the request in the order they are defined. When a route matching the request is found, no further routes are considered. Thus, you need to list your routes in order of decreasing specificity.
However, your first route matches more requests than your second route, i.e. it is less specific than the second route:
When ASP.NET MVC tries to match the request for Home/Index to your routes, it will match the first route because it will consider Home to be the productName, it will consider Index to be the controller name and the rest of the parameters are not required.
You need to reorder your routes or make the first route more specific. This could be done by putting constraints on the productName parameter.
UPDATE
Without knowing anything about your products and their names, it is impossible for me to suggest an appropriate constraint. Maybe you could use a numeric SKU and have a constraint like
routes.MapRoute(
name: "ProductRoute",
url: "{productName}/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { productName = #"\d+" }
);
forcing productName to be numeric.
Alternatively, you could change the url to
"products/{productName}/{controller}/{action}/{id}"
For more on constraints see this link or use Google.

For route configuration
routes.MapRoute(
name: "ProductRoute",
url: "{productName}/{controller}/{action}/{id}",
defaults: new { productName = 'put your method name to get productName over here', controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "your namespace of controller" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });

Related

MVC routes are in conflict

I need to have 2 routes in my ASP.NET MVC application, and I am having difficulty trying to define the routes in a way that they don't steal from each other.
I need to handle urls like
www.website.com/Home/About
www.website.com/Home/Contact
I also need to urls like this
www.website.com/23a244x3/Products/2
www.website.com/434e5s344/Services/1
www.website.com/f2432g423/Profile
So I need 2 routes.
The urls in #1 are successfully handled by the default route, which is
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
To handle the urls in #2, I have defined the following route
routes.MapRoute(
name: "PagesRoute",
url: "{uniqueID}/{action}/{pagecount}",
defaults: new { controller = "Pages", pagecount = UrlParameter.Optional }
);
Unfortunately now the route #2 (aka PagesRoute) is also handling the urls from #1, such as www.website.com/Home/About. I also have url rewrite rules set in IIS that turn all urls into lowercase, for SEO purposes, so /Home redirects to /home etc.
How can I differentiate these two routes? The route in #2 seems to be greedy..
You would have to not provide controller, and provide routes for each controller:
routes.MapRoute(
name: "Default",
url: "Home/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
To the parser {uniqueID} and {controller} are essentially the same. Any string in the Url, will match both routes, so you need something to differentiate the 2.
You can also take a look into Route Constraints:
routes.MapRoute(
"PagesRoute",
"{uniqueID}/{action}/{pagecount}",
new { controller = "Pages", pagecount = UrlParameter.Optional },
new { uniqueID = #"\d+" }
);

Disabling Default Routes on Asp.net Mvc

I am using Asp.net Mvc 5 with C#.
I want to disable default routing in my project. My map routes like;
routes.MapRoute(name: "News",
url: "haberler",
defaults: new { controller = "News", action = "Index"});
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
When a user visits my website's news page, it's like;
www.domain.com/haberler
But also the user can visit the news page as below;
www.domain.com/news
I want to remove that "/news" or direct to seo-friendly url like; "/haberler"
So how can I disable default routing (Controller-Name-Convension) routing?
Instead of removing the "default" route, you can add a controller constraint to it
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { controller = #"(Account|Manage|Home)" }
);
Like this, /news will return 404 Not Found.
In MVC, the convention is to map URLs to a particular Action on a particular Controller. Remove default route to disable default convention:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
www.domain.com/news will not match in any of your routes hence it will throw an error.
Try removing with this
RouteTable.Routes.Remove(RouteTable.Routes["NAME ROUTE YOU WISH TO RMOVE"]);
Hope this will helps you.

Custom MVC Routes

So I just got to routes on my first big MVC app and its giving me a headache.
All /Category/Subcategory goes to the ProductController.Index(string category, string subcategory). If I don't specify a Subcategory it will show me all items in the Category (Fords, Audis etc)
If I have my routes like this, url /Home/About goes to Product/Index with parameters: Category=Home, Subcategory=About.
If I move the default to the top, url /Car/Ford does not go anywhere since I don't have a CarController (I don't want a controller for every category.)
I'd really like to not have another segment like /store/Car/Ford..
Do I need to create a route for every "main" Category and hardcode the name?
Help me solve this problem!
// http://localhost/Car/Ford (note: Car can be replaced by bike, plan, boat etc.)
routes.MapRoute(
name: "AllProductsInCategoryOrSubcategory",
url: "{category}/{subcategory}",
defaults: new { controller = "Products", action = "Index", subcategory = UrlParameter.Optional }
);
// http://localhost/Car/Ford/ABC123/Explorer
// http://localhost/Car/Ford/ABC123
routes.MapRoute(
name: "Kakel",
url: "{category}/{subcategory}/{id}/{productName}",
defaults: new { controller = "Products", action = "Details", productName = UrlParameter.Optional }
);
// http://localhost/Home/About
// http://localhost/Products/RenderImage/ABC123 (used to render image in details view)
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
you can use the route constraints to solve this problem. let say for your first route AllProductsInCategoryOrSubcategory you can add constraint like this. Here I am using you have only one category at this time that is car.
routes.MapRoute(
name: "AllProductsInCategoryOrSubcategory",
url: "{category}/{subcategory}",
defaults: new { controller = "Products", action = "Index",
subcategory = UrlParameter.Optional },
new {category = "^car$"}
);
Because of this route constraints MVC will select this route when the category name will be car.
One important point is you need to add defaults value prior to the route constraints. Because while selecting route MVC will first select default value then will apply constraint.

Rewriting url in asp.net-mvc4 (razor) with extention

Default of asp.net-mvc4 is http://domainname.com/products/1 with routes
routes.MapRoute(
name: "Products",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional }
);
and I want to rewrite to http://domainname.com/products/1.html that has .html extention .
Any ideas for this?
Do you mean this:
routes.MapRoute(
name: "Products",
url: "{controller}/{action}/{id}.html",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional }
);
Why would you want to put .html extension to a query string or route parameter?
if you take a website with html files, the extension is with the page not with the parameters. Don't know if you have any specific requirement to put it always at the end of the url. but it doesn't make any sense.
routes.MapRoute(
name: "Products",
url: "{controller}/{action}.html/{id}",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional }
);
you might have problems with iis after doing the above, please take a look at this discussion as well.
ASP.NET MVC Routing - add .html extension to routes

Add routing in case of missing "action" in url ({controller}/{id})

How can I set up a {controller}/{id} routing in ASP.NET MVC 5.
What I would like to achieve: if there are no {action} defined, call Index() with id.
I tried thism but didn't work:
// Keep default routing
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
// Add own routing in case of missing "action"
routes.MapRoute(
name: "Controller/Id",
url: "{controller}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
After reading ameer's comment it become clear that the routing is not that "intelligent" that I was hoping for, so if the URL pattern is matching one route, but no such controller/method found, it will not "fall through" to the next routing command, but will raise exception.
So I had tried what Simon suggested, added constraint to my custom routing, and reversed the order, and it works now. However, if I would like to have other mappings similar to attachments, I'd have to add them one by one.
Working code:
routes.MapRoute(
name: "Attachments",
url: "attachments/{id}",
defaults: new { controller = "Attachments", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Categories

Resources