Configure asp.net mvc hocalhost/Home/Products to hocalhost/Products - asp.net-mvc-3

How to configure asp.net mvc routing to get
hocalhost/Products and hocalhost/Search
instead of
hocalhost/Home/Products and hocalhost/Home/Search
i.e. to remove Controller name from the route?
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Products", id = UrlParameter.Optional } // Parameter defaults
);

routes.MapRoute(
"Default",
"{action}/{id}",
new { controller = "Home", action = "Products", id = UrlParameter.Optional }
);
Thus:
http://example.com/ => controller=Home, action=Products
http://example.com/Products => contoller=Home, action=Products
http://example.com/Search => contoller=Home, action=Search

Related

I want to set MVC route

I want to set routing, when the user will write a URL like www.abc.com/param1, it's auto-redirect or call to
www.abc.com/itemview/index/param1
www.abc.com/itemview/index/ is a fixed part.
I tried with the below route but it was not worked?
routes.MapRoute(name: "Default",
url: "ItemsViewNew/Index/{id}",
defaults: new { controller = "ItemsViewNew", action = "Index", id = UrlParameter.Optional }
);

multiple parameter to Url.Action does not generate proper routing path even after defining routes in Asp.net Mvc 4

I have following code
#(Url.Action("Files","Folder", new RouteValueDictionary(new {fileGroup = group,fileName= name, ticket = nodeId})))
I have routes defined
routes.MapRoute(
name: "FolderFiles",
url: "Folder/Files/{fileGroup}/{fileName}/{ticket}/{path}",
defaults:
new
{
controller = "Folder",
action = "Files",
fileGroup = UrlParameter.Optional,
fileName = UrlParameter.Optional,
ticket= UrlParameter.Optional,
path = UrlParameter.Optional
}
);
which generates
http://mydomain.com/Folder/Files?fileGroup=Temp&fileName=Test2&ticket=461c9a67aa94
but i want following url generated
http://mydomain.com/Folder/Files/Temp/Test2/461c9a67aa94/
is it possible to get the above desired url formation?
thanks.
In your case the default route should be handled first.
Try to put your route definition after the default one.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "FolderFiles",
url: "Folder/Files/{fileGroup}/{fileName}/{ticket}/{path}",
defaults:
new
{
controller = "Folder",
action = "Files",
fileGroup = UrlParameter.Optional,
fileName = UrlParameter.Optional,
ticket = UrlParameter.Optional,
path = UrlParameter.Optional
}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
To link your action :
#Html.ActionLink("My link", "Files", "Folder", new {fileGroup ="Group1", fileName = "file1", ticket = "ticke1", path ="path1"}, null)
Or execute it :
#(Html.Action("Files","Folder", new {fileGroup = "Group1",fileName= "file1", ticket = "ticke1", path ="path1"}))

What kind of route would I need to provide vanity urls?

I'd like to provide my users a vanity url, something like:
www.foo.com/sergio
What kind of route would I need to create?
Imagine I have the following controller and action, how can I map a vanity URL to that controller?
public ActionResult Profile(string username)
{
var model = LoadProfile(username);
return View(model);
}
Here is what I've tried and what happens:
Option A:
Every url is caught in this route, meaning every URL I type directs me towards the Account controller, instead of only foo.com/[USERNAME]. No good.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Profile",
"{username}",
new { controller = "Account", action = "Profile", username = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Option B:
Default routes work well, but when trying to visit a profile foo.com/[USERNAME] I get an HTTP 404 error.
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(
"DentistProfile",
"{username}",
new { controller = "Account", action = "Profile", username = UrlParameter.Optional }
);
}
one solution could be using custom route constraint as,
public class VanityUrlContraint : IRouteConstraint
{
private static readonly string[] Controllers =
Assembly.GetExecutingAssembly().GetTypes().Where(x => typeof(IController).IsAssignableFrom(x))
.Select(x => x.Name.ToLower().Replace("controller", "")).ToArray();
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
return !Controllers.Contains(values[parameterName].ToString().ToLower());
}
}
and use it as
routes.MapRoute(
name: "Profile",
url: "{username}",
defaults: new {controller = "Account", action = "Profile"},
constraints: new { username = new VanityUrlContraint() }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
downside of this approach, profile view for usernames same as existing controller name will not work, like if there are usernames like "asset", "location", and "AssetController", "LocationController" exists in project, profile view for "asset", "location" will not work.
hope this helps.
Have you tried:
routes.MapRoute(
"YourRouteName",
"{username}",
new {controller="YourController", action="Profile", username=UrlParameter.Optional}
);
This should trap www.foo.com/{username}. Remember that routes are checked in the order you add them, so you can add
routes.MapRoute(
"default",
"{controller}/{action}/{input}",
new {controller="controller", action="action", input=UrlParameter.Optional}
);
first to maintain the "default" behavior.

ASP MVC 3 switching language with ActionLink

In an ASP MVC 3 project i want to enable language switching.
The routing is defined like this:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"DefaultWithLanguage", // Route name
"{language}/{controller}/{id}/{slug}", // URL with parameters
new { language = "en", controller = "Front", action = "Details", id = UrlParameter.Optional, slug = 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
);
Trying to switch languages (in _Layout.cshtml) works like this:
<li>#Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" })</li>
Instead of getting a URL like the following (after having selected Spanish)
.../es/ControllerName/ActionName
i 'm getting this:
.../ControllerName/ActionName?Length=11
If i set the ActionLink to the following (notice the last null parameter):
<li>#Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" }, null)</li>
i get this:
.../ControllerName/ActionName?language=es
What am i missing?
Thanks in advance!
There are some issues with your routes registration DefaultWithLanguage route registration. It doesn't allow you to specify the {action}. This means that this route will only match a Details action (since you have specified it in the default values). Another issue is that you made the {id} parameter optional. But that's impossible. Only the last parameter of a route can be optional. In your case it is followed by a {slug} parameter.
So one possibility is the following:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"DefaultWithLanguage",
"{language}/{controller}/{action}/{id}",
new
{
language = "en",
controller = "Front",
action = "Details",
id = UrlParameter.Optional
}
);
}
and then:
#Html.ActionLink(
"Spanish",
ViewContext.RouteData.GetRequiredString("action"),
ViewContext.RouteData.GetRequiredString("controller"),
new { language = "es" },
null
)
If you wanted to add a {slug} parameter then your {id} can no longer be optional:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"DefaultWithLanguage",
"{language}/{controller}/{action}/{id}/{slug}",
new
{
language = "en",
controller = "Front",
action = "Details",
slug = UrlParameter.Optional
}
);
}
and then:
#Html.ActionLink(
"Spanish",
ViewContext.RouteData.GetRequiredString("action"),
ViewContext.RouteData.GetRequiredString("controller"),
new {
language = "es",
id = ViewContext.RouteData.GetRequiredString("id")
},
null
)
This is a follow up to Darin's answer.
I want to have routes like this:
.../en/ControllerName/Id
.../en/ControllerName/Id/Slug
.../en/ControllerName
This last route causes the problem (see the answer of Darin). The "hack" to keep getting this routes is to define also another route (the second named DefaultWithLanguageWithoutId) :
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"DefaultWithLanguage", // Route name
"{language}/{controller}/{id}/{slug}", // URL with parameters
new { language = "en", controller = "Front", action = "Details", id = UrlParameter.Optional, slug = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"DefaultWithLanguageWithoutId", // Route name
"{language}/{controller}", // URL with parameters
new { language = "en", controller = "Front", action = "Details"} // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
This is causing the code to be adjusted in the master page to the following
<li>#Html.ActionLink("Deutsch", ViewContext.RouteData.Values["action"].ToString()
, ViewContext.RouteData.Values["controller"].ToString(), new { language = "de"
, id = ViewContext.RouteData.Values["id"]!=null ? ViewContext.RouteData.Values["id"].ToString():null }, null)</li>
<li>#Html.ActionLink("English", ViewContext.RouteData.Values["action"].ToString()
, ViewContext.RouteData.Values["controller"].ToString(), new { language = "en"
, id = ViewContext.RouteData.Values["id"] != null ? ViewContext.RouteData.Values["id"].ToString() : null }, null)</li>
Works perfect!
The only "drawback" is the fact that there is some code involved (i would have liked to avoid) in the view, but i think it is worth since it is very simple!

Simple Html.Actionlink question (MVC3)

The Route:
routes.MapRoute(
"Items", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Item", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
The htmlhelper:
#Html.ActionLink("Chairs", "List", "Item", new {id="Chairs"}, null)
The link it generates:
http://localhost:57899/Item/List?id=Chairs
What I want it to show:
http://localhost:57899/Item/List/Chairs
How to do that?
Instead of using ActionLink what happens if you try the following?
#Html.RouteLink("Items", new { id = "Chairs" })
You call Html.RouteLink (not Action Link) and map an additional route under your generic like this:
routes.MapRoute(
"ChairsRoute", // Route name
"Item/List/{id}", // URL with parameters
new {controller = "Item", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
when you call RouteLink, you'll simply pass that "ChairsRoute" name

Resources