Routing to action getting only one ID from the URL - c#

Im trying to make a custom router for my mvc-learning project.
I want to keep the standrard route that directs to {controller}/{action}/{id} in case of a URL like
domain.com/user/details/72
but if i get a url like this one
domain.com/2
i want to route to a specifik controller action that takes the number as an id. So i dont want the URL to specify controller and action, cause i want the url to be real short and the controller and action should always be the same.
Ive kind of made it work but i get very strange unpredictable results so i wanted to ask if im doing something very weird. Here are my routes:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DisplayKombak",
url: "{kombakId}",
defaults: new { controller = "Kombak", action = "DisplayKombak", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

Try something like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DisplayKombak",
url: "{kombakId}",
defaults: new {controller = "Kombak", action = "DisplayKombak"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
}
And KombakController.cs:
using System.Web.Mvc;
namespace WebApplication1.Controllers
{
public class KombakController : Controller
{
public ActionResult DisplayKombak(string kombakId)
{
return View();
}
}
}

You may be able to force this behavior by adding route constraints.
routes.MapRoute(
name: "DisplayKombak",
url: "{kombakId}",
defaults: new { controller = "Kombak", action = "DisplayKombak", id = UrlParameter.Optional },
new {kombakId = #"\d+" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new {controller = #"\D+" }
);
The constraint on the first route will prevent the route from matching unless the first route segment is an integer, the constraint on the second route will prevent the route from matching if the first route segment is not a string of letters.

Related

how to use routes with controller and without controller

I have multi controller and Area in website. I want use url without controller for default controller name. so use this coded for route:
routes.MapRoute(
name: "WithOutController",
url: "{action}/{id}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
This working. But working for all controller, not only default controller. I also tried this code:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "WithOutController",
url: "{action}/{id}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
}
But this code working only url with controller. I want it to work this way:
Default/Index: url(http://localhost:2470/Index)
Default/Login: url(http://localhost:2470/Login)
Panel/Index: url(http://localhost:2470/Panel/Index)
No sure how many actions your default controller need to be mapped to a URL without the default name on it. But if it is only two you can try this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DefaultIndex",
url: "Index/{id}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "DefaultLogin",
url: "Login/{id}",
defaults: new { controller = "Default", action = "Login", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
}
Another option is to enable MapMvcAttributeRoutes and decorate your actions with the desired routes.
To enable MapMvcAttributeRoutes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Default", action = "About", id = UrlParameter.Optional }
);
}
Then in your default controller you need to:
[Route("Index")]
public ActionResult Index()
{
return View();
}
[Route("Login")]
public ActionResult Login()
{
return View();
}
Your default action name MUST be something different to the Route Attributes names.

Defining multiple static routes and 1 dynamic route for 1 controller in .NET MVC

I have defined a couple of static routes which look like following:
routes.MapRoute(
name: "LogOutRoute",
url: "Index/LogOut",
defaults: new { controller = "Index", action = "LogOut" }
);
routes.MapRoute(
name: "Tutorials",
url: "Index/Tutorials",
defaults: new { controller = "Index", action = "Tutorials" }
);
And third is the dynamic route which looks like following:
routes.MapRoute(
name: "Index",
url: "Index/{id}",
defaults: new { controller = "Index", action = "Index" }
);
I would like to have defined these two static routes for my Index controller:
/Index/Tutorials
/Index/LogOut
Every other route should point to:
/Index/{id}
The way I defined it right now works for 2 static routes, but when I try to pass parameter like this which isn't one of the two static routes like following:
http://localhost:60617/Index/12345/
Where 12345 is ID, I get following error:
The resource cannot be found.
How can I define these routes properly ? Can someone help me out ?
Here is the route class:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "LogOutRoute",
url: "Index/LogOut",
defaults: new { controller = "Index", action = "LogOut" }
);
routes.MapRoute(
name: "Tutorials",
url: "Index/Tutorials",
defaults: new { controller = "Index", action = "Tutorials" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Index",
url: "Index/{id}",
defaults: new { controller = "Index", action = "Index" }
);
routes.MapRoute(
name: "ResetPwdRoute",
url: "{controller}/{action}/{id}",
defaults: new { controller = "User", action = "ResetPwd", id = UrlParameter.Optional }
);
}
}
The order in which you map routes are important.
Generic routes should be mapped after more specific routes to avoid route conflicts.
public class RouteConfig {
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "LogOutRoute",
url: "Index/LogOut",
defaults: new { controller = "Index", action = "LogOut" }
);
routes.MapRoute(
name: "Tutorials",
url: "Index/Tutorials",
defaults: new { controller = "Index", action = "Tutorials" }
);
routes.MapRoute(
name: "Index",
url: "Index/{id}",
defaults: new { controller = "Index", action = "Index" }
);
routes.MapRoute(
name: "ResetPwdRoute",
url: "User/ResetPwd/{id}",
defaults: new { controller = "User", action = "ResetPwd", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

MVC RedirectToAction not hiding parameters

I have the following action
public ActionResult TemplateBuilder(int id, int? processId) { }
And then I have the following
#Url.Action("TemplateBuilder","InspectionTemplate")/id/processId
The url then looks like: InspectionTemplate/TemplateBuilder/1/2
But if I use
return RedirectToAction("TemplateBuilder","InspectionTemplate", new { id=1, processId = 2});
Then I get the following result: InspectionTemplate/TemplateBuilder/1?processId=2
How can I fix that.
Here is my Routing
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "IDRoute",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "Login",
action = "Index",
id = UrlParameter.Optional
}
);
routes.MapRoute(
name: "ProcessRoute",
url: "{controller}/{action}/{id}/{processId}",
defaults: new
{
controller = "InspectionTemplate",
action = "TemplateBuilder",
id = UrlParameter.Optional,
processId = UrlParameter.Optional
}
);
routes.MapRoute(
name: "DateRoute",
url: "{controller}/{action}/{year}/{month}/{day}",
defaults: new
{
controller = "Inspection",
action = "Assign",
year = UrlParameter.Optional,
month = UrlParameter.Optional,
day = UrlParameter.Optional
}
);
}
You have 3 issues with your route definitions
Only the last parameter in a route definition can be marked with
UrlParameter.Optional. If you were to provide only one, then the
routing engine has no way of knowing which parameter should be bound
so the value(s) would be added as query string parameters).
The main issue however is the order of the routes. The routing
engines searches the definitions in the order they are declared and
stops as soon as it finds a matching one, and in your case the
IDRoute will match so the routes need to be swapped.
That alone however may cause issues with other route definitions, so
its best to make your route uniquely identifiable, for example by
specifying the controller name in the route definition.
Your definitions should be
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "ProcessRoute",
url: "InspectionTemplate/{action}/{id}/{processId}",
defaults: new { controller = "InspectionTemplate", action = "TemplateBuilder", processId = UrlParameter.Optional }
);
routes.MapRoute(
name: "DateRoute",
url: "Inspection/{action}/{year}/{month}/{day}",
defaults: new { controller = "Inspection", action = "Assign", } // assumes all parameters are required
);
// The default will only be match if the url does not start with '/InspectionTemplate/' or '/Inspection/'
routes.MapRoute(
name: "IDRoute",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
}

Default Routes not redirecting to expected page in mvc

I have a HomeController in which I have 2 ActionResults say Index and Projects. Now my RouteConfig.cs has below routes added:
routes.MapRoute(
name: "Default_1",//Changed this to some other name
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",//Made this name as Default
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Projects", id = UrlParameter.Optional }
);
So from the above configuration I was expecting by the default the user will redirected to /Home/Projects. But again it is redirecting to Index action. Why it is not redirecting to Projects action? Can't we have multiple routes here?Default name will not be considered as default url?
When you register your routes,put your specific route definition(s) before the default route definition. The order of route registration matters.
routes.MapRoute(
name: "Project",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Projects", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
With this configuration, Any requests coming will be redirected to your Home/Projects because the url pattern is still the generic pattern({controller}/{action}/{id}). So i guess you really meant something like this.
routes.MapRoute(
name: "Project",
url: "projects/{id}",
defaults: new { controller = "Home", action = "Projects", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
This will send the request http://yourSite.com/Projects to Home/Projects
Or you may use attribute routing to define this route pattern in the Projects controller.To enable attribute routing, you can call the MapMvcAttributeRoutes method in the RegisterRoutes method of RouteConfig.cs. You will still keep the default route definition there.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
And in your ProjectsController
[Route("Projects/{id?}")]
public ActionResult Index(int? id)
{
//check id value and return something
}

URL Rewriting on my ASP .NET MVC website

I'm working on an image viewer, so I've a controller named Viewer and when I pass it routeValues it is passed in the URL like this :
http://www.mywebsite.com/Viewer?category=1&image=2
Here is the link used to get on this page :
#Url.Action("Index", new { category = p.Category, image = p.Image })
But I do like to have this URL :
http://www.mywebsite.com/Viewer/1/2
I have tried to do a few tricks in the RegisterRoutes method of the RouteConfig class but I can not get the previous result.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Viewer",
url: "{controller}/{action}/{category}-{image}",
defaults: new { controller = "Viewer", action = "Index", category = 1, image = 1 }
);
}
}
Does anyone know where I can do this?
Thanks a lot !
You need to put your more specific route before the default route, because the routes are evaluated in the same order in which you declared them:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Viewer",
url: "{controller}/{action}/{category}/{image}",
defaults: new { controller = "Viewer", action = "Index", category = 1, image = 1 }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

Categories