I am kinda blocked with some routing issues in my ASP.NET MVC application.
Let us assume I have 2 controllers which are:
TaskList Controller
Task Controller
I'm not sure if this is overkill or not but I am aiming to have URL's as follows:
For TaskList Controller:
localhost:xxxx/tasklist/Create
localhost:xxxx/tasklist/
localhost:xxxx/tasklist/Details/1
localhost:xxxx/tasklist/Edit/1
For Task Controller:
localhost:xxxx/tasklist/1/Task/Create
localhost:xxxx/tasklist/1/Task
localhost:xxxx/tasklist/1/Task/Details/11
localhost:xxxx/tasklist/1/Task/Edit/11
I have set up my routing as follows:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "TaskListRoute",
url: "TaskList/{action}/{tasklistid}",
defaults: new { controller = "TaskList", action = "Index", tasklistid = UrlParameter.Optional }
);
routes.MapRoute(
name: "TaskRoute",
url: "TaskList/{tasklistid}/{controller}/{action}/{taskid}",
defaults: new { tasklistid = UrlParameter.Optional, controller = "Task", action = "Index", taskid = UrlParameter.Optional }
);
Upon debugging the application, I am able to browse the TaskList controller with no problems but the moment I hit the following url on the Task Controller, I get a "Resource cannot be found" error:
http://localhost:xxxx/tasklist/1/Task
I have to type in the word "Index" like below in order for that page to work...
http://localhost:xxxx/tasklist/1/Task/Index
The method signature behind the above url is...
public class TaskController : Controller
{
// GET: Task
public ActionResult Index(int tasklistid)
{
//Some code here....
}
}
Any ideas where I wrong? Appreciate any advice.
Thanks in advance.
So after taking Nkosi's comment and NightOwl888's article into consideration all I had to do was modify the routing to look like the following:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "TaskRoute",
url: "TaskList/{tasklistid}/Task/{action}/{taskid}",
defaults: new { controller = "Task", action = "Index", taskid = UrlParameter.Optional }
);
routes.MapRoute(
name: "TaskListRoute",
url: "TaskList/{action}/{tasklistid}",
defaults: new { controller = "TaskList", action = "Index", tasklistid = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
}
Basically did the following:
Adjust routing to be in following order:
TaskRoute
TaskListRoute
Default
In the TaskRoute, replaced '{controller}' with a literal like 'Task'
which is actually the name of the controller.
I hope this was the right thing to do.
Cheers
Related
I'm working in MVC 5 and have taken over a project. When I log onto the homepage "mydomain.com" it comes up with an error:
"Server Error in '/' Application. The resource cannot be found. Description: HTTP 404. Requested URL:/"
If I type in mydomain.com/home/index it comes up with the home page as it should. I figure this is a RouteConfig.cs problem, but everything looks pretty default to me.
namespace Source
{
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: "Glossary2",
url: "{controller}/{action}/{letter}",
defaults: new { controller = "Teacher", action = "Glossary2", letter = UrlParameter.Optional }
);
/* Will need to finish this later.
* When the contact us form is submitted, it should redirect to Home/Contact/{state}
* where {state} can be either 'Success' or 'Error', which will display
* an alert component in the view based on the provided {state}.
*/
routes.MapRoute(
name: "ContactSuccess",
url: "{controller}/{action}/{submissionStatus}",
defaults: new { controller = "Home", action = "Contact", submissionStatus = UrlParameter.Optional }
);
/* Will need to finish this later.
* When the contact us form is displayed, it should check to see if a reason for contacting
* us is already set. If it is, it should automatically select the appropriate reason on the
* dropdown menu.
*/
routes.MapRoute(
name: "ContactReason",
url: "{controller}/{action}/{reason}",
defaults: new { controller = "Home", action = "Contact", reason = UrlParameter.Optional }
);
}
}
}
I'm not sure what the CustomeViewEngine is doing and haven't really messed around with it yet. I've also inspected the Global.asax.cs file and it looks pretty standard as well.
namespace Source
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ViewEngines.Engines.Add(new CustomViewEngine());
}
}
public class CustomViewEngine : RazorViewEngine
{
public static readonly string[] CUSTOM_PARTIAL_VIEW_FORMATS = new[]
{ "~/Views/Selection/{0}.cshtml" };
public CustomViewEngine()
{
base.PartialViewLocationFormats = base.PartialViewLocationFormats.Union(CUSTOM_PARTIAL_VIEW_FORMATS).ToArray();
}
}
}
Is there a way to trace down why the domain name is not getting routed to home/index? If I put the Default mapping at the bottom of the RouteConfig file it wants to automatically direct to the login page. Again, I'm not really understanding why this would be acting this way.
I think your route definitions are not in right order, the route order evaluates from top to bottom (the most specific path resolved first).
Hence, the default route should be take place as the last defined route:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// custom path at the top (or top-most depending on priority)
routes.MapRoute(
name: "Example",
url: "Example/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
// default path at the bottom-most
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Additionally, all URLs defined in every route in the sample are in same pattern (using {controller}/{action}/{parameter}), hence it potentially conflict between each other. You can use plain strings to differentiate similar route patterns:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Glossary2",
url: "Teacher/{action}/{letter}",
defaults: new { controller = "Teacher", action = "Glossary2", letter = UrlParameter.Optional }
);
routes.MapRoute(
name: "ContactSuccess",
url: "{controller}/{action}/SubmissionStatus/{submissionStatus}",
defaults: new { controller = "Home", action = "Contact", submissionStatus = UrlParameter.Optional }
);
routes.MapRoute(
name: "ContactReason",
url: "{controller}/{action}/Reason/{reason}",
defaults: new { controller = "Home", action = "Contact", reason = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Note: Use RouteDebugger to find out which routes handled by RouteConfig when accessing specific routes.
I have two route with same signature but only the parameter names are different how to fix this issue.
Following is my code
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "DefaultRoute2",
url: "{controller}/{action}/{formSubmissionId}",
defaults: new { controller = "Employee", action = "Index", formSubmissionId = "formSubmissionId" }
);
The routes are meant to accept different URL structures. Both of your routes have same structure, so the first one will always match, and the second will never be tested.
Instead of using a different route, in /Employee/Index you should just use the parameter id.
public class EmployeeController : Controller
{
public ActionResult Index(string id)
{
string formSubmissionId = id;
}
}
The URL for that action would be the same that (I believe) you wanted to achieve with the second route: Employee/Index/id
UPDATE
I've just realized. If you only need the parameter formSubmissionId for the action /Employee/Index you could do this:
// Note the order of the routes:
routes.MapRoute(
name: "DefaultRoute2",
url: "Employee/Index/{formSubmissionId}",
defaults: new { controller = "Employee", action = "Index", formSubmissionId = "formSubmissionId" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
);
public class EmployeeController : Controller
{
public ActionResult Index(string formSubmissionId)
{
// ...
}
}
Now i fix this issue as
routes.MapRoute(
name: "DefaultActivity",
url: "{controller}/LoadActivity/{formSubmissionId}",
defaults: new { controller = "{controller}", action = "LoadActivity", formSubmissionId = UrlParameter.Optional }
);
this is work around of my scenario.
This is my default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
My controller is "Home" and my view is "Index" and it takes these arguments with defaults:
public class HomeController : Controller
{
public ActionResult Index(string Queue = "ALL", string Summary = "false")
{
...
}
}
My current URL looks like this:
http://www.example.com/?Queue=ONE&Summary=true
But I would like it to be routed to something like this:
http://www.example.com/ONE?Summary=true
Basically routing it so I don't have to use the Queue keyword in the URL.
Modify your route definition like below,
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{Queue}",
defaults: new { controller = "Home", action = "Index", Queue = UrlParameter.Optional }
);
I have home controller and Index action method. The below url works
http://localhost/home/index
Will it be possible to make it work like below
http://localhost/index.aspx
I am trying below code in Global.asax but does not works
routes.MapPageRoute("MyPage", "create.aspx", "~/home/create");
Route Config
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapPageRoute("MyPage", "create.aspx", "~/home/create");
routes.MapRoute(
name: "Customized",
url: "{action}",
defaults: new { controller = "Home", action = "Default", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Reports",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Reports", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Default", id = UrlParameter.Optional }
);
}
You should use MapRoute() instead of MapPageRoute(), as you are still referring to an MVC controller/action:
routes.MapRoute(
name: "Default2",
url: "index.aspx",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
PS: Remember to register the new route before other ones which may eventually interfere with it.
You can't MapPageRoute for non static content as you are doing. If you wan't to hide the Controller for your route the Customized already do this. If you are mixing MVC + WebForms you should fallow this guide to se how config your routes.
How to: Define Routes for Web Forms Applications
I have a controller named Registration and an action method in it as the following:
public JsonResult GetReqs(GridSettings gridSettings, int rt)
{
...//whatever
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
So I added a route and now my RouteConfig.cs is like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "RegReq",
url: "{Registration}/{GetReqs}/{rt}",
defaults: new { controller = "Registration", action = "GetReqs", rt = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
However I can't access the rt parameter and the action method GetReqs isn't called(I set a breakpoint on it but nothing happened). Where is the mistake?
Edit: Link example I tried : ~/Registration/GetReqs/1
I think you need to remove the brackets in your first route:
routes.MapRoute(
name: "RegReq",
url: "Registration/GetReqs/{rt}",
defaults: new { controller = "Registration", action = "GetReqs",
rt = UrlParameter.Optional }
);
The default route has {controller} to tell MVC to use the string in that section of the url as the controller name. You know the controller, so you just need to match the specific string.