Asp.net MVC custom routing with SEO - seo

routes.MapRoute(
"Route",
"{id}/{*seostuff}",
new {controller = "Home", action="Index", seo = UrlParameter.Optional});
that will allow you to map urls such as http://www.somesite.com/11/whatever/goes-here/will-be-whatever-you/want
Here is the original post Asp.net MVC custom routing
Hi guys!
-what I want to know is how can this be code in controller? I have a static page like this Product/Phone/i-phone.aspx which is under the product it has a folder phone.. . any suggestion guys? thank you very much.. .

You can define the route you have described...
routes.MapRoute(
"Route", // ShopsToRent/0/B31 5EH/9/0/0/0/0/0
"{id}/{seo}", // URL with parameters
new
{
controller = "ControllerName",
action = "ActionName",
page = UrlParameter.Optional,
title = ""
} // Parameter defaults
);
I personally prefer to have a Keyword at the start of the url as this gives you an additional keyword (eg www.keywords.com/keywords )and allows future additions to the site...
routes.MapRoute(
"Route", // ShopsToRent/0/B31 5EH/9/0/0/0/0/0
"KEYWORD/{id}/{seo}", // URL with parameters
new
{
controller = "ControllerName",
action = "ActionName",
page = UrlParameter.Optional,
title = ""
} // Parameter defaults
);

Related

Optional middle parameter in MVC4 Route

I am trying to create a controller action that receives several parameters for filtering a scope and then the final parameter is a required paging parameter for paging the results.
//Example Action
public ActionResult Details(string time, string regionscope, string localscope = null, int page = 1) {
}
//RouteConfig.cs
routes.MapRoute(
name: "LocationWithLocalScopeRoute",
url: "/Details/{time}/{regionscope}/{localscope}/{page}",
defaults: new
{
controller = "Location",
action = "Details",
localscope = UrlParameter.Optional
}
);
Is there anyway I can exclude the localscope parameter but still have the page parameter be interpreted as the page number by the controller (while still maintaining pretty URLs)?
// Test URLs
/Details/May-17/Mid/1
/Details/May-17/Mid/Bumville/1
I know I could add a route before the existing route:
//RouteConfig.cs
routes.MapRoute(
name: "LocationWithNoLocalScopeRoute",
url: "/Details/{time}/{regionscope}/{page}",
defaults: new
{
controller = "Location",
action = "Details"
}
);
I also realize I could put page before any of the other parameters.
routes.MapRoute(
name: "LocationWithLocalScopeRoute",
url: "/Details/{page}/{time}/{regionscope}/{localscope}",
defaults: new
{
controller = "Location",
action = "Details",
localscope = UrlParameter.Optional
}
);
Was just wondering if there was a way to make it work all in one route definition while still having the Test URLs work.
No, not without creating another specific route or making localscope the last parameter.
When using routing, only the last parameter can be marked as UrlParameter.Optional. If more that one is optional, then the routing engine has no way to know which route segment applies to which method parameter.
In your case when the url is ../Details/May-17/Mid/1, is the last segment with the value of 1 the value for localscope or the value for page? There is no way to determine that, so if you were to generate the url using #Url.Action() (or one of the other methods that generate url's), then the url will be generated with query string values, not route values.

Create Link to level up controller using Razor in ASP.NET MVC4

This is my code that i'm using to create a link to top level link:
#Html.ActionLink("Edit",Url.Action("Edit","Home", new{row.Application_ID}))
// supposed to return /Home/Edit/x (application_id)
Instead, it returns:
/Home/Home/Edit/x // Current View is Home/Edit
Please help.
Edit 1:
Route Table information:
//This is for Edit
routes.MapRoute(
"Edit", // Route name
"Home/Edit/{application_id}", // URL with parameters
new { controller = "Home", action = "Edit", application_id = UrlParameter.Optional } // Parameter defaults
);
// This is the default route, I've modified it to LogOn.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Account", action = "LogOn", id = UrlParameter.Optional } // Parameter defaults
);
As a small edition to haim770 answer. if you want for some reason use Url.Action instead Html.ActionLink you are always free to write it like that:
Edit
Some developers prefere this way because it more similar to plain Html, but result is the same as Html.ActionLink
You don't need the inner #Url.Action, try this instead:
#Html.ActionLink("Edit", "Edit", "Home", new { application_id = row.Application_ID }, null);
tried this work around and it worked:
Edit
now it returns the link as Home/Edit/x :)

MVC4 URL Routing : Optional parameter

In my MVC4 application, I want to show the data to users according to the client. I want to achieve this using URL routing.
e.g.
1. http://mysite.com/abc/account/login
2. http://mysite.com/xyz/account/login
Here, 'abc' and 'xyz' are referred as clientcode. If user enters first url, then the application will connect to database for client 'abc'. If user enters second url, then it will connect to database for client 'xyz'.
I want to achieve the above functionality. So how should i make use of routing.
I have used following code in RouteConfig -
routes.MapRoute(
name: "Default",
url: "{clientcode}/{controller}/{action}/{id}",
defaults: new { clientcode = UrlParameter.Optional, controller = "Account", action = "Login", id = UrlParameter.Optional }
);
Thanks in advance.
You can only make the last parameter optional in ASP.NET MVC. Instead of changing the default route, create a new route for this specific URL. Make sure you add this one before the default route.
routes.MapRoute(
name: "Login",
url: "{clientcode}/account/login",
defaults: new { clientcode = UrlParameter.Optional, controller = "Account", action = "Login" }
);
You can achieve this by reading ControllerContext.RouteData. The RouteData object contains Values RouteValueDictionary that you can read and query for clientcode. For example:
var clientCode = ControllerContext.RouteData.Values["clientcode"];
if (String.IsNullOrWhiteSpace(clientCode))
{
// Set to a default value
clientCode = "default_value";
}
// Do something with clientCode
return ViewResult(); // or RedirectToAction("ActionName")
That's about it.

Generate wrong outgoing url because of segment variable reuse in MVC 4

Here is my RouteConfig.cs
routes.MapRoute(null,
"{controller}/Page{page}",
new {controller = "Product", action = "Index", category = (string) null},
new {page = #"\d+"}
);
routes.MapRoute(null,
"{controller}/{category}",
new {controller = "Product", action = "Index", page = 1}
);
routes.MapRoute(null,
"{controller}/{category}/Page{page}",
new {controller = "Product", action = "Index"},
new {page = #"\d+"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
And here is the code for generating url:
#Html.ActionLink("View Cart", "Index", "ShoppingCart", null, new { #class = "btn btn-orange" })
It works well when I navigate to, for example, Product/Page2, Product/Laptop, Product/Laptop/Page2. The problem is, whenever my current URL contains Page segment, it will try to reuse that segment for generating outgoing URL. So, if I'm at Product/Page2 the above generated URL would be ShoppingCart/Page2. I don't know how to avoid this.
Please help me. Thank you so much.
EDIT!!!
I've found a workaround way. Instead of using ActionLink, I use RouteLink like this:
#Html.RouteLink("View Cart", "Default", new { controller = "ShoppingCart", action = "Index" }, new { #class = "btn btn-orange" })
But I still want to use ActionLink, so please help me.
EDIT!!!
The workaround way doesn't work when I generate a link to ShoppingCart/Checkout. It still take me to Index action in ShoppingCart controller.
Create a new route pattern specific to ShoppingCart and make it the first route by placing it at the TOP.
routes.MapRoute(null,
"ShoppingCart/{action}",
new {controller = "Product"});
);
As a rule all the specific routes should come first.
This is because of the way the routing system tries to evaluate the value of segment variables when trying to match against a route.
So when the call to render the link occurs with the following arguments:
#Html.ActionLink("View Cart", "Index", "ShoppingCart", null, new { #class = "btn btn-orange" })
the framework when evaluating the route with template
{controller}/Page{page}
will resolve the controller segment variable to be ShoppingCart however when it cannot find a value for the page segment variable (via any of the arguments in the method call), it will then try and resolve that value from the RouteData object in the ViewContext. Since you have navigated to Product/Page2, the current value of page within the routes value dictionary is 2.
You can inspect this by looking at the value of ViewContext.RouteData.Values["page"] when rendering that view.

MVC routing error

I have a custom route defined:
routes.MapRoute(
"FabricDetails", // Route name
"fabric/details/{designerUrlFriendlyName}/{collectionUrlFriendlyName}/{fabricUrlFriendlyName}", // URL with parameters
new { controller = "Fabric", action = "Details", designerUrlFriendlyName = UrlParameter.Optional, collectionUrlFriendlyName = UrlParameter.Optional, fabricUrlFriendlyName = UrlParameter.Optional }, // Parameter defaults
new[] { "StashFabrics.Web.Controllers" }
);
I have two nearly identical actionlinks and one is working while the other is not
#Html.ActionLink(fabric.FabricName, "Details", "Fabric", new RouteValueDictionary(new { designerUrlFriendlyName = fabric.DesignerUrlFriendlyName, collectionUrlFriendlyName = fabric.CollectionUrlFriendlyName, fabricUrlFriendlyName = fabric.FabricUrlFriendlyName }), null)
#Html.ActionLink(fabric.FabricName, "Details", "Fabric", new RouteValueDictionary(new { designerUrlFriendlyName = fabric.DesignerUrlFriendlyName, collectionUrlFriendlyName = "grand_hotel", fabricUrlFriendlyName = fabric.FabricUrlFriendlyName }), null)
For whatever reason, as soon as I replace the hard coded value for collectionUrlFriendlyName the link doesn't get built correctly
http://localhost:55089/Fabric/Details?designerUrlFriendlyName=jenean_morrison&collectionUrlFriendlyName=grand_hotel&fabricUrlFriendlyName=ballroom_in_azure
http://localhost:55089/fabric/details/jenean_morrison/grand_hotel/ballroom_in_azure
This has me stumped. Any advice would be appreciated.
Well I figured it out.
In the model of the view I have collectionUrlFriendlyName defined at two different levels; first on the model itself and then again on the class to which the model has a list.
I wasn't defining a value for collectionUrlFriendlyName at the list level, where the URL was being formed. But I guess when constructing the URL it would later find the value at the upper level and use it to form the ugly url (thus hiding the problem that it wasn't populated on the lower level)
If that make sense.