I want to be able to handle any url that s requested via some controller.
foo.com/a
foo.com/abcd
foo.com/x1
for foo.com/a
I want to process it with
UrlHandlerController with Process(string url) method.
How should i add a routing rule to be able to do this?
Any ideas?
Create a new custom route and use Phill Haack's Route Debugger to test your routes:
routes.MapRoute(
"customroute",
"{url}",
new { controller = "UrlHandler",
action = "Process",
url = ""
}
);
Controller:
public class UrlHandlerController : Controller
{
[HttpGet]
public ActionResult Process(string url)
{
return View();
/* or */
if(url == "something"){
return View("SomethingView");
}
else if(url == "somethingelse"){
return View("SomethingElseView");
}
}
}
Darth, see if this route helps:
routes.MapRoute(
"CustomRoute", // Route name
"{url}", //Route formation
new { controller = "UrlHandler", action = "Process" }, // Where to send it
new { keyWord = #"\S+" } // Regex to identify the argument
);
Regards.
Related
I'm having problems with the routings in my MVC project not working...
I want all my views in the Views > Shared folder like this:
Error.cshtml (default)
Index.cshtml (default)
Overview.cshtml (custom that I made)
Recordings.cshtml (custom that I made)
I've then created one shared controller to handle all views like this:
public class SharedController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Error()
{
return View();
}
public ActionResult Overview()
{
return View();
}
public ActionResult Recordings()
{
return View();
}
}
My RouteConfig.cs looks like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Map to specific pages under Shared controller:
routes.MapRoute("SharedPages", "{action}/{id}",
new { controller = "Shared", action = #"Overview|Recordings", id = UrlParameter.Optional });
// Use the default rout for all other pages:
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Shared", action = "Index", id = UrlParameter.Optional }
);
// Show the Error page for anything else (404):
routes.MapRoute("Error", "{*url}",
new { controller = "Shared", action = "Error" }
);
}
I want the routing to work like this:
://(url)/ (root - no action specified) --> Shared/Index.cshtml
://(url)/Index --> Shared/Index.cshtml
://(url)/Overview --> Shared/Overview.cshtml
://(url)/Recordings --> Shared/Recordings.cshtml
://(url)/whatever (or if an error occurs) --> Shared/Error.cshtml
But it's not working as expected. If I go to ://(url)/ (root), I get a HTTP 404 - The resource cannot be found. If I go to for example ://(url)/Overview, it's working fine.
How can I make it work like I want?
The order of how you map route is important and first matched route wins. That means that even if there is no resource there one it matches the route it will use it.
public static void RegisterRoutes(RouteCollection routes)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Use specific rout for all other pages:
routes.MapRoute("WhateverA", "WhateverA/{action}/{id}",
new { controller = "WhateverA", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute("WhateverB", "WhateverB/{action}/{id}",
new { controller = "WhateverB", action = "Index", id = UrlParameter.Optional }
);
// Map to specific pages under Shared controller:
routes.MapRoute("RootPages", "{action}/{id}",
new { controller = "Shared", action = "Index", id = UrlParameter.Optional });
// Show the Error page for anything else (404):
routes.MapRoute("Error", "{*url}",
new { controller = "Shared", action = "Error" }
);
}
The problem with the Default and SharedPages routes is that they conflict with each other. You may need to provide specific routes for other controllers if they exist. Other wise the other option is to use Attribute Routing for the other controllers and convention-based routing for your root routes and error
public static void RegisterRoutes(RouteCollection routes)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//Attribute routing
routes.MapMvcAttributeRoutes();
// Map to specific pages under Shared controller:
routes.MapRoute("RootPages", "{action}/{id}",
new { controller = "Shared", action = "Index", id = UrlParameter.Optional });
// Show the Error page for anything else (404):
routes.MapRoute("Error", "{*url}",
new { controller = "Shared", action = "Error" }
);
}
With controllers decorated accordingly
[RoutePrefix("WhatEver")]
public class WhatEverController : Controller {
//GET whatever
[HttpGet]
[Route("")]
public ActionResult Index() { ... }
}
I am looking to do something like:
For categories where the Controller will be CategoryController
www.mysite.com/some-category
www.mysite.com/some-category/sub-category
www.mysite.com/some-category/sub-category/another //This could go on ..
The problem is that: www.mysite.com/some-product needs to point to a ProductController. Normally this would map to the same controller.
So, how can I intercept the routing so I can check if the parameter is a Category or Product and route accordingly.
I am trying to avoid having something like www.mysite.com/category/some-category or www.mysite.com/product/some-product as I feel it will perform better on the SEO side. When I can intercept the routing, I'll forward to a product / category based on some rules that look at slugs for each etc.
You could write a custom route to serve this purpose:
public class CategoriesRoute: Route
{
public CategoriesRoute()
: base("{*categories}", new MvcRouteHandler())
{
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var rd = base.GetRouteData(httpContext);
if (rd == null)
{
return null;
}
string categories = rd.Values["categories"] as string;
if (string.IsNullOrEmpty(categories) || !categories.StartsWith("some-", StringComparison.InvariantCultureIgnoreCase))
{
// The url doesn't start with some- as per our requirement =>
// we have no match for this route
return null;
}
string[] parts = categories.Split('/');
// for each of the parts go hit your categoryService to determine whether
// this is a category slug or something else and return accordingly
if (!AreValidCategories(parts))
{
// The AreValidCategories custom method indicated that the route contained
// some parts which are not categories => we have no match for this route
return null;
}
// At this stage we know that all the parts of the url are valid categories =>
// we have a match for this route and we can pass the categories to the action
rd.Values["controller"] = "Category";
rd.Values["action"] = "Index";
rd.Values["categories"] = parts;
return rd;
}
}
that will be registered like that:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add("CategoriesRoute", new CategoriesRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
and then you can have the corresponding controller:
public class CategoryController: Controller
{
public ActionResult Index(string[] categories)
{
... The categories action argument will contain a list of the provided categories
in the url
}
}
I have some dynamic user route like
routes.MapRoute(
"UserNames", // Route name
"{username}", // URL with parameters
new { controller = "Home", action = "UserName" });
and under the HomeController.cs
public ActionResult UserName(string username)
{
ViewBag.Message = username;
return RedirectToAction("Register","Account"); // Test...
}
It is working fine.
But what I need is to get working the URL like
http:\\mywebsite.com\UserNameBob\MyGallery\1
http:\\mywebsite.com\UserNameBob\Profile
http:\\mywebsite.com\UserNameBob\MyFriends
How do I can archive it?
Any clu?
Thank you!!!
Do you mean something like this:
routes.MapRoute(
"UserNames", // Route name
"{username}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "UserName", id = UrlParameter.Optional });
And then in HomeController you put actions like these:
public ActionResult MyGallery(string username, int id) {
// code
}
public ActionResult Profile(string username) {
// code
}
EDIT: Of course, if the gallery ID is not an int, just use string or whatever is appropriate.
Look for URL Rewriting in ASP.NET to handle the dynamic parameters while routing.
I have a controller that looks like this:
public class PageController : Controller
{
public ActionResult Render(string url)
{
//this is just for testing!
return Content("url was " + url);
}
}
I'm trying to pass in the value of the url into the controller. For example:
http://www.site.com/products/something/else
Would pass "products/something/else" into my Render action of the PageController.
This is because we are using "products/something/else" as a unique key for a record in the database (legacy system, don't ask)
So, my resultant query would be something along the lines of this:
select * from foo where urlKey = 'products/something/else'
So far I have this in my RegisterRoutes section on Global.asax:
routes.MapRoute("pages", "{*url}", new { controller = "Page", action = "Render", url="/" });
But this isn't working as expected...
By visiting www.site.com/products/something/else, the value passed into the controller is "home/index/0"
The only route defined in RegisterRoutes is that described in the question.
The below class matches every route but you can modify as per your needs.
public class LegacyRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
string url = httpContext.Request.RawUrl.Substring(1);
result = new RouteData(this, new MvcRouteHandler());
result.Values.Add("controller", "Page");
result.Values.Add("action", "Render");
result.Values.Add("url", url);
return result;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
In Global.asax.cs
routes.Add(new LegacyRoute());
Hope this helps, one of our routes does something similar and this is the code:
routes.MapRoute(
name: "Standard",
url: "{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional, action = ControllersAndActions.TypicalController.IndexAction, page = 1 },
constraints: new
{
controller = ControllersAndActions.ControllerConstraintExpression
}
);
I'm trying to read the a parameter that I've defined in a route from inside the controller.
The route:
routes.MapRoute(
"BusinessVoice", // Route name
"business/{controller}/{action}/{id}", // URL with parameters
new { controller = "Voice", action = "Index",
id = UrlParameter.Optional, locale = "business" } // Parameter defaults
);
From inside the controller I'd like to be able to read the route parameter locale, but have not idea where to look for it.
The controller:
namespace www.WebUI.Controllers
{
public class VoiceController : Controller
{
public VoiceController()
{
... want to read the locale param here
}
public ViewResult Index(string locale)
{
return View();
}
}
}
Any help is appreciated!
Dave,
This is from my basecontroller but you should be able to do exactly the same from a top level one too:
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
var locale = requestContext.RouteData.Values["locale"].ToString() ?? System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
base.Initialize(requestContext);
}
good luck
jim
public VoiceController()
{
var locale = this.RouteData.Values["locale"];
}