URL route Catch all - asp.net-mvc

I wondering if there is anyway to achieve a url like http://www.mycompany.com/user in MVC
I tried using the catch all but could not get the user passed so I can do the look up.
Thanks

Something like this?
routes.MapRoute("User",
"{UserName}",
new { Controller = "User", Action = "Index", UserName = "" });
UPDATED:
add this constraint to the "User" route:
routes.MapRoute("User",
"{UserName}",
new { Controller = "User", Action = "Index", UserName = "" },
new { UserName = #"(\w|-)+" }
);
or add this route:
routes.MapRoute("Home",
String.Empty,
new { Controller = "Home", Action = "Index", Id = "" }
);

Related

UrlHelper.Action not generating pretty url

I'm generating SEO-friendly "Pretty URLs" using this custom route, inspired by posts here on stackoverflow:
// Route used for Details view
routes.Add("CarDetailsRoute", new SeoFriendlyRoute(
url: "car/{state}/{community}/{make}/{model}/{slug}-{id}",
valuesToSeo: new string[] { "state", "community", "make", "model", "slug" },
defaults: new RouteValueDictionary(new { controller = "Vehicle", action = "Details", slug = UrlParameter.Optional, state = UrlParameter.Optional, community = UrlParameter.Optional, make = UrlParameter.Optional, model = UrlParameter.Optional }),
constraints: new RouteValueDictionary(new { id = #"\d+" })
));
/// The interesting route
routes.Add("CarIndexRoute", new SeoFriendlyRoute(
url: "car/{state}/{community}/{make}/{model}/",
valuesToSeo: new string[] { "state", "community", "make", "model" },
defaults: new RouteValueDictionary(new { controller = "Vehicle", action = "Index", state = UrlParameter.Optional, community = UrlParameter.Optional, make = UrlParameter.Optional, model = UrlParameter.Optional })
));
// Unrelated routes
// Fallback default route
routes.Add("Default", new SeoFriendlyRoute(
url: "{controller}/{action}/{id}",
valuesToSeo: new string[] { "action", "controller" },
defaults: new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional }))
);
However, when I'm generating the breadcrumbs from my Details view to generate generic searches on parts of the details information, somehow the custom route fails and the default route kicks in.
// RequestContext here being a full qualified with Make, Model, Community
// and State. These are inserted in to all .Action()s by default, so i have
// to "remove them" where I don't want them.
var url = new UrlHelper(Request.RequestContext);
var breadcrumbs = new List<IBreadcrumbLink>() {
new BreadcrumbLink() {
Title = vehicle.Dealer.State,
Url = url.Action("Index", new { model = string.Empty, make = string.Empty, community = string.Empty })
// Doesn't work, generates ~/vehicle/?model=aaa&make=bbb&community=ccc&state=ddd
// Expected ~/car/state/
},
new BreadcrumbLink() {
Title = vehicle.Dealer.Community,
Url = url.Action("Index", new { model = string.Empty, make = string.Empty })
// Works, generates ~/car/state/community/
},
new BreadcrumbLink(){
Title = vehicle.Make,
Url = url.Action("Index", new { model = string.Empty })
// Works, generates ~/car/state/community/make/
},
new BreadcrumbLink(){
Title = vehicle.Model,
Url = url.Action("Index")
// Works, generates ~/car/state/community/make/model/
}
};
What would cause this behavior? Visiting the expected url of ~/car/state/ works like a charm, but as stated I cannot generate this url?

MVC 3 routing help with dynamic route

Im trying to do something like this:
routes.MapRoute("Product", "{product}/{id}",
new
{
action = "Product",
controller = "Home",
product = UrlParameter.Optional,
id = UrlParameter.Optional
});
It gives me error when im trying to load page 404 i think,
Im trying to make the url look like this: www.tables.com/productName/ID .
How can i do it without adding a strong type word like this:
routes.MapRoute("Product", "Products/{product}/{id}", ... )
rest of the routes:
routes.MapRoute("Product", "{product}/{id}",
new
{
action = "Product",
controller = "Home",
product = UrlParameter.Optional,
id = UrlParameter.Optional
});
routes.MapRoute("Category", "Category/{category}/{template}",
new
{
action = "Index",
controller = "Category",
category = UrlParameter.Optional,
template = UrlParameter.Optional
});
routes.MapRoute("Profile", "Profile/{fullName}",
new
{
action = "Index",
controller = "Profile",
fullName = UrlParameter.Optional
});
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
thanks.
Your problem is that the Product route will match everything not starting with Category or Profile.
I would place the product route just before the default route and use a IRouteConstraint such that it doesn't match non products.
Code sample:
routes.MapRoute("Category", "Category/{category}/{template}",
new
{
action = "Index",
controller = "Category",
category = UrlParameter.Optional,
template = UrlParameter.Optional
});
routes.MapRoute("Profile", "Profile/{fullName}",
new
{
action = "Index",
controller = "Profile",
fullName = UrlParameter.Optional
});
routes.MapRoute("Product", "{product}/{id}",
new
{
action = "Product",
controller = "Home",
product = UrlParameter.Optional,
id = UrlParameter.Optional
},
new { product = new ProductRouteConstraint() });
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
And the route constraint:
public class ProductRouteConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (routeDirection == RouteDirection.IncomingRequest &&
parameterName.ToLowerInvariant() == "product")
{
var productName = values[parameterName] as string;
if (productName == null)
return false;
var productId = values["id"] as string;
if (productId == null)
returns false;
return ProductCatalogue.HasProductById(productId);
}
return false;
}
}
The ProductCatalogue should obviously be replaced with however you lookup products in your system.

Re-use route parameter on url

How do I make my application route to mydomainname/username/controller.
I am working on asp.net mvc web application that enables a user to belong to multiple account. ie. In the application every account has its own users, and each user in one account can also be a user in another account. What i need is when a user wants to login, they specify the account they want to be logged to like this: domainname.com/accountname/login.
Am able to do this, but where am having issue is how to persist the accountname route parameter across other routes? I mean making it to be visible on the url. For now am using cookie to store and get the accountname parameter, but i need a way to make it visible on the url in every request (without having to manually route it on links) until the user singout.
Am using asp.net mvc 2
Edit: Added my route code
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("", "", new { controller = "Home", action = "index" });
routes.MapRoute("", "dashboard", new { controller = "account", action = "dashboard" });
routes.MapRoute("", "contacts", new { controller = "contact", action = "index" });
routes.MapRoute("", "groups", new { controller = "group", action = "index" });
routes.MapRoute("", "sms", new { controller = "sms", action = "index" });
routes.MapRoute("", "users", new { controller = "user", action = "index" });
routes.MapRoute("", "login", new { controller = "Home", action = "login", accountUrlName = UrlParameter.Optional });
routes.MapRoute("", "{accountUrlName}/login", new { controller = "Home", action = "login" });
routes.MapRoute("", "register", new { controller = "home", action = "register" });
routes.MapRoute("", "{accountUrlName}/invitations/{ivkey}", new { controller = "home", action = "invitations" });
routes.MapRoute("", "{urlName}",
new { controller = "home", action = "index", urlName = UrlParameter.Optional });
routes.MapRoute("", "{accountUrlName}/{action}",
new { controller = "account", action = "dashboard", id = "", accountUrlName = UrlParameter.Optional });
routes.MapRoute("", "{accountUrlName}/{controller}/{action}/{id}",
new { controller = "account", action = "dashboard", id = "", accountUrlName = ""});
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
So you effectively have two sets of routes here -
{AccountName}/{Controller}/{Action} and {Username}/{Controller}/{Action}.
Is this right?
It's possible for you to create these routes, but you'd have to have usernames which do not contain account names, and vice versa.

Help me get this ASP.NET MVC2 RC ActionLink to work?

I could have SWORN I had this working, but somewhere along the line I apparently broke it. Maybe it was during my migration from ASP.NET MVC in VS2008 to ASP.NET MVC2 in VS2010.
My ActionLink:
Html.ActionLink(segment.TitleWithChapterNumber, "Index", "Read", new { bookCode = Model.Product.Id, segmentCode = segment.Index }, null)
The route I expect it to match:
routes.MapRoute(
"Read",
"Read/{bookCode}/{segmentCode}/{sectionCode}/{renderStrategy}",
new { controller = "Read", action = "Index", bookCode = "", segmentCode = "", sectionCode = "", renderStrategy = "" }
);
This renders a link that looks like: http://localhost/Obr/Read?bookCode=14&segmentCode=0
But I want it to look like http://localhost/Obr/Read/14/0
Clicking the link that it renders does take me to the right controller and the response is accurate. If I paste in the link I WANT it to look like, it does work. I guess it's just not matching?
Am I missing something obvious? I've stared at it so long I don't even know what I am looking for anymore.
For reference, here are ALL of my routes:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"ReadImage",
"Read/Image/{bookId}/{imageName}",
new { controller = "Read", action = "Image" }
);
routes.MapRoute(
"Read",
"Read/{bookCode}/{segmentCode}/{sectionCode}/{renderStrategy}",
new { controller = "Read", action = "Index", bookCode = "", segmentCode = "", sectionCode = "", renderStrategy = "" }
);
routes.MapRoute(
"BookReport",
"BookReport/{action}/{folder}",
new { controller = "BookReport", action = "Details", folder = "" }
);
routes.MapRoute(
"Reference",
"Reference/Details/{referenceType}/{searchText}",
new { controller = "Reference", action = "Details", referenceType = "", searchText = "" }
);
routes.MapRoute(
"PaginatedAudits", // Route name
"Audit/Page/{pageNumber}", // URL with parameters
new { controller = "Audit", action = "Index" } // Parameter defaults
);
routes.MapRoute(
"PaginatedReadLog", // Route name
"ReadLog/Page/{pageNumber}", // URL with parameters
new { controller = "ReadLog", action = "Index" } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
The action signature looks like this:
[Authorize]
public ActionResult Index(string bookCode, string segmentCode, string sectionCode, string renderStrategy)
{
// code
}
Try a route link by explicitly giving the name of the route:
Html.RouteLink(
segment.TitleWithChapterNumber, // linkText
"Read", // routeName
new {
bookCode = Model.Product.Id,
segmentCode = segment.Index
}, // routeValues
null // htmlAttributes
)
Your route definitions should have UrlParameter.Optional instead of empty strings.
routes.MapRoute(
"Read",
"Read/{bookCode}/{segmentCode}/{sectionCode}/{renderStrategy}",
new { controller = "Read", action = "Index", bookCode = UrlParameter.Optional, segmentCode = UrlParameter.Optional, sectionCode = UrlParameter.Optional, renderStrategy = UrlParameter.Optional }
);
This will also help with redirect in controllers and form urls created through MVC extensions.

ASP.NET MVC custom routes with optional args

I want a Route with two optional args; I thought the following would work:
routes.MapRoute(
"ProductForm",
"products/{action}/{vendor_id}_{category_id}",
new { controller = "Products", action = "Index", vendor_id = "", category_id = "" },
new { action = #"Create|Edit" }
);
But it only works when both vendor_id and category_id are provided; using RouteDebug I see that /products/create/_3 doesn't trigger my route, so I added other two routes:
routes.MapRoute(
"ProductForm1",
"{controller}/{action}/_{category_id}",
new { controller = "Home", action = "Index", category_id = "" },
new { controller = "Products", action = #"Create|Edit" }
);
routes.MapRoute(
"ProductForm2",
"{controller}/{action}/{vendor_id}_",
new { controller = "Home", action = "Index", vendor_id = "" },
new { controller = "Products", action = #"Create|Edit" }
);
So, the questions:
Is using three routes the only way to make a route with optional args?
Are these URLs ok or not, that is, would you suggest a better way to do this?
Why don't you try to give vendor_id a default value (if it is not specified i.e 0) that would help you get away with one route
routes.MapRoute("ProductForm","products/{action}/{vendor_id}_{category_id}",
new { controller = "Products", action = "Index", vendor_id = "0", category_id = "" },
new { action = #"Create|Edit" });
looks good to me but i would do it a little different:
routes.MapRoute(
"ProductForm1",
"product/category/{category_id}",
new { controller = "Home", action = "Index", category_id = "" },
new { controller = "Products", action = #"Create|Edit" }
);
and then
routes.MapRoute(
"ProductForm1",
"product/details/{product_id}",
new { controller = "Home", action = "Index", product_id = "" },
new { controller = "Products", action = #"Create|Edit" }
);
then your class can be as follows:
ActionResults Index(){}
ActionResults Index(int category_id){// get categories}
ActionResults Index(int product_id){ // get products}
but thats just me
you could try it like this:
routes.MapRoute(
"ProductForm",
"products/{action}/{arg1}/{arg1_id}/{arg2}/{arg2_id}",
new { controller = "Products", action = "Index", arg1 = "", arg2 = "", arg1_id = "", arg2_id = "" },
new { action = #"Create|Edit" });
Then you would create some logic in your actionresult method to check arg1 and arg2 and identify wich argument has been passed in.
your actionlink urls would look like this:
/products/create/vendor/10
/products/create/category/20
/products/create/vendor/10/category/20
/products/create/category/20/vendor/10
Personally i dont like this as the route doesn't seem very clean but should give you what i think your looking to achieve?

Resources