I can't get a catch all route to work in MVC. I have tried to implement what is shown in this question, but it does not work. I have a controller called OnlineController with an Index action. My RouteConfig.cs is set up like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id =
UrlParameter.Optional }
);
routes.MapRoute("RouteName", "{*url}", new { controller =
"Online", action = "Index" });
}
Browsing to the following URL
Blockquote http://mysite/online/something
gives a 404. Why is it not caught and redirected to the index action on the Online controller?
If you want to catch all routes you should delete "Default" route:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute("RouteName", "{*url}", new { controller = "Online", action = "Index" });
}
Routes are chosen in the order they were mapped and your url matches "Default" route.
If you want to catch some routes for existing controllers and actions you can use your "Default" route, but with constraints:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { controller = "Home|Home2", action = "Index|Index2"}
);
routes.MapRoute("RouteName", "{*url}", new { controller =
"Online", action = "Index" });
}
Now, if you controller name is "Home" or "Home2" and action name is "Index" or "Index2" these routes will be handled by existing controllers and actions, if other names - by "Online" controller
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 would like to create a dynamic routing to a URL like following:
http://localhost:51577/Item/AnyActionName/Id
Please note that the controller name is static and doesn't need to be dynamic. On the other hand, I need to have the action name part dynamic so that whatever is written in that part of URL, I would redirect the user to the Index action inside of Item controller.
What I have tried so far is:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Items",
"Item/{action}/{id}",
new { controller = "Item", action = "Index", id = UrlParameter.Optional });
}
And when I build my app I get a following error:
The resource cannot be found.
Edit:
Here is my Global.asax file and the routeconfig.cs file:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
And here's the content of the RouteConfig.cs file with the answer that #Nkosi provided:
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: "Items",
url: "Item/{id}/{*slug}",
defaults: new { controller = "Item", action = "Index", slug = UrlParameter.Optional }
);
}
}
What you are referring to in your question is called a slug.
I answered a similar question here for web api
Web api - how to route using slugs?
With the slug at the end the route config would look like this
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Items",
url: "Item/{id}/{*slug}",
defaults: new { controller = "Item", action = "Index", slug = RouteParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
which could match an example controller action...
public class ItemController : Controller {
public ActionResult Index(int id, string slug = null) {
//...
}
}
the example URL...
"Item/31223512/Any-Item-Name"
would then have the parameters matched as follows...
id = 31223512
slug = "Any-Item-Name"
And because the slug is optional, the above URL will still be matched to
"Item/31223512"
With ASP.NET MVC, I have code as below and the standard route definition. When I navigate to mysite.com/ExtjsRun I get a 403.14 error but when I go to mysite.com/ExtjsRun/index I get the controller executed.
My question is how to get the route /ExtjsRun to default to my index method.
using System.Web.Mvc;
using WebApp.Models;
namespace WebApp.Controllers
{
public class ExtJsRunController : Controller
{
[MultiTenantControllerAllow("svcc,angu")]
public ActionResult Index()
{
var str = "/ExtjsRun/" + Tenant.Name;
return Redirect(str);
}
}
}
Routing:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
namespaces: new[] {"WebApp.Controllers"},
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home",
action = "Index",
id = UrlParameter.Optional }
);
Change the Routing code as below
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
namespaces: new[] {"WebApp.Controllers"},
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "ExtJsRun",
action = "Index",
id = UrlParameter.Optional }
);
You are not set the default controller to ExtJsRun and action to Index. By your code, the iis server searches for the Home controller and Index Action in that controller, that's the reason for your access denial
Hope this helps
I have a controller name Dashboard and inside that controller i have an action AdminDashboard . Now by default url of this action becomes /Dashboard/AdminDashboard . I want to map this action to this url /SupervisorDashboard
This is what i am doing but its saying not found
routes.MapRoute(
name: "SupervisorDashboard",
url: "SupervisorDashboard",
defaults: new { controller = "Dashboard", action = "AdminDashboard" }
);
and also how can i redirect to this page using Url.Action
Global.asax
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "SupervisorDashboard",
url: "SupervisorDashboard",
defaults: new { controller = "Dashboard", action = "AdminDashboard" }
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
Have you placed this new route definition before default route? Routes are evaluated in the same order in which they were registered. If you put default route before any of custom routes, it will be used (and since you probably don't have any SupervisorDashboardController in code, 404 will be returned).
Url.Action should work correctly, if routes are defined in correct order.
So, for this case, RouteConfig should look like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// this one match /SupervisorDashboard only
routes.MapRoute(
name: "SupervisorDashboard",
url: "SupervisorDashboard",
defaults: new { controller = "Dashboard", action = "AdminDashboard" }
);
// should be last, after any custom route definition
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
I am using mvc4 framework and .net framwork 4.5. I need a url like this:
www.examples.com/name (note: 'name' will be change dynamically)
which routes to the same page.
I have tried like this but getting error
My action method is like this:
public ActionResult Userlist(string status)
{
return View();
}
Route Config
routes.MapRoute(
"user",
"{status}",
new { controller = "Home", action = "Userlist" }
);
How can I create a route syntax and redirect this to a controller?
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Add this route config
routes.MapRoute(
name: "Default_Userlist",
url: "{status}",
defaults: new { controller = "Home", action = "Userlist" },
namespaces: new[] { "MyMvcProject.Controllers" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "MyMvcProject.Controllers" }
);
}
Don't forget to replace the "MyMvcProject" with the name of your project.
Issue
This is a bad practice because the value of the status could easily cause conflicts with your action methods.