how to simulate IgnoreRoute in my custom MvcRouteHandler - asp.net

In my ASP.NET MVC3 App I try simulate "routes.IgnoreRoute("...")"
I create CustomMvcRouteHandler:
public class CustomMvcRouteHandler: MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
// do something
....
return base.GetHttpHandler(requestContext);
}
}
in my Global.asax.cs file i have:
protected void Application_Start()
{
// ............
RegisterRoutes(RouteTable.Routes);
// ............
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("elmah.axd");
//routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new CustomMvcRouteHandler();
}
How can I do this ?

I'm not entirely sure what you mean in your question, but I'll try to answer it...
To simulate an IgnoreRoute all you need to do is associate an instance of the StopRoutingHandler from your route. If you're using the built-in ASP.NET "Route" class then you would do something like this:
routes.MapRoute(
"Ignore-This", // Route name
"ignore/{this}/{pattern}" // URL with parameters
).RouteHandler = new StopRoutingHandler();
Anything that matches that pattern will cause the routing system to immediately stop processing any more routes.
If you want to write your own custom route (for example, a new route type that derives from RouteBase), then from its GetRouteData method you need to return the StopRoutingHandler.

#Eilon is the correct answer. Here is an alternative syntax that feels more MVCish.
routes.Add("Ignore-This",
new Route(
"ignore/{this}/{pattern}",
new StopRoutingHandler())
);

Related

MapPageRoute fails to redirect to specified aspx page

I have the following in my RouteConfig.cs file
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 }
);
// route default URL to index.aspx
routes.MapPageRoute(
routeName: "LoginPageRoute",
routeUrl: "login",
physicalFile: "~/Login.aspx"
);
routes.MapPageRoute("LoginPageRoute2", "login2", "~/Login.aspx");
}
However if I try to access my WebApp using "login" or "login2" I get a resource cannot be found error message.
http://localhost:4200/login2 - fails
http://localhost:4200/login - fails
http://localhost:4200/Login.aspx - loads fine
My Global.asax has the following
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
A comment from somebody under my question guided me to the solution which was to move my custom routes ahead of the default routes.
Adding the following to Global.asax helped prove that this was indeed the issue.
public override void Init()
{
base.Init();
this.AcquireRequestState += showRouteValues;
}
protected void showRouteValues(object sender, EventArgs e)
{
var context = HttpContext.Current;
if (context == null)
return;
var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(context));
}
Putting a breakpoint on
var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(context));
Showed that my "login" mapping was using the default route mapping instead of my custom route mapping.
Thanks again #mason!

.NET MVC 5 Only one area not working under IIS

I have problem with one area in my project called 'Reports'. I always get 404 error when I try to access some controller from this Area. This problem only occurs when I run my application on local IIS (Windows 8.1). On other machine (windows 7 and local IIS) everything is ok. Even on this windows 8.1 machine, but IIS Express everything is working well.
I was trying to clear temp files, but no resuls.
Areas are registed such like this:
public class ReportsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Reports";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Reports_default",
"Reports/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
And in Global.asax, Application_start() method:
AreaRegistration.RegisterAllAreas();
I dont know where could be the problem. Do you have any ideas?
Check event viewer. I had this problem and the 'Reports' URL was a virtual directory having to do with SQL Server Reporting Services.
Try this:
public class ReportsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Reports";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Reports_main",
"Reports/{controller}/{action}/{id}",
new { area = "Reports", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"Reports_default",
"Reports/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
The Reports_default routing rule sets Index to be the default action for a given controller.
You need to add another Reports_main rule that will set a default controller when you access the root of the area e.g. /Reports. In this rule I assume that the default controller is Home but you can change that to fit your project.
The default AreaRegistration scaffold by Visual Studio does not include a default for controller, meaning that providing a controller in the URL is required.
/Reports/Home // This works (if you have a home controller)
/Reports // This doesn't work
To make the controller optional, you need to provide a default.
public class ReportsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Reports";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Reports_default",
"Reports/{controller}/{action}/{id}",
// Note that controller is defaulted to Home
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Note also that the order in which routes are registered is the same that they will be executed for the entire application. Typically, this means that you must call AreaRegistration.RegisterAllAreas() before you call RouteConfig.RegisterRoutes(RouteTable.Routes).
The answer provided by Tasos will also work, but is incorrectly configured:
Specifying a default area within an AreaRegistration is redundant and unnecessary.
Reports_default in his example is an unreachable execution path, which makes it also redundant and unnecessary.

Keep MVC.NET automatic routing, but add additional specific routes

I have a MVC.NET application that used the default routing engine to connect {controller}/{action}/{*pathInfo} and everything works fine. I've added some WCF services to the project and need to setup specific routes to reach them. The problem I'm running into is when I add the specific routes, the default automatic routing no longer functions. How can I either use the default route handler with some overrides, or if that is not possible setup a generic route handler that automatically handles all existing Controllers/Actions and static resources?
public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(new ServiceRoute("services/rest/InvoiceService", new WebServiceHostFactory(), typeof(InvoiceService)));
routes.Add(new ServiceRoute("services/soap/InvoiceService", new ServiceHostFactory(), typeof(InvoiceService)));
routes.Add(new ServiceRoute("services/soap/LoginService", new ServiceHostFactory(), typeof(LoginService)));
routes.Add(new ServiceRoute("services/rest/LoginService", new WebServiceHostFactory(), typeof(LoginService)));
/** WHAT GOES HERE? **/
routes.MapHttpRoute("Default", "{controller}/{action}/{*pathInfo}",
new { controller = "Home", action = "Index", id = "" });
}
protected void Application_Start()
{
//RouteConfig.RegisterRoutes(RouteTable.Routes); //OLD code that automatically handled routing
RegisterRoutes(RouteTable.Routes); //NEW code
}
I figured it out - for posterity, you need to add a constraint clause to the MapRoute MVC handler that excludes the pattern you have for the WCF services. Here is the final code block that worked. The key part was the REGEX to exclude services as a valid controller name.
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 },
constraints: new { controller = #"^(?!services)\w+$" }
);
RouteTable.Routes.Add(new ServiceRoute("services/rest/InvoiceService", new WebServiceHostFactory(), typeof(InvoiceService)));
RouteTable.Routes.Add(new ServiceRoute("services/soap/InvoiceService", new ServiceHostFactory(), typeof(InvoiceService)));
RouteTable.Routes.Add(new ServiceRoute("services/soap/LoginService", new ServiceHostFactory(), typeof(LoginService)));
RouteTable.Routes.Add(new ServiceRoute("services/rest/LoginService", new WebServiceHostFactory(), typeof(LoginService)));
}

URL Rewriting in Asp.net MVC 3

I am new to Asp.net MVC.
I am creating web application, where i have to rewrite url with product name.
I am not sure if that is possible or not in MVC.
Like,
http://sitename.com/category1/product1
http://sitename.com/category1/product2
will have same page.
There are facilities to generate friendly urls within MVC.
Check out the article at - http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/asp-net-mvc-routing-overview-cs - for an overview of how this is handled in MVC.
Essentially, you need to configure the routes on application startup as follows. This can usually be done in the global.asax file but cna be split for areas etc.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes); // Reigster the routes
}
This is the default route but you can define as required.

Multiple types were found that match the controller named 'Home'. (Two Areas, Same controller name)

This is probably a duplicate to many but the obvious answers in them do not solve my problem.
I get:
Multiple types were found that match the controller named 'Home'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
The request for 'Home' has found the following matching controllers:
App.Web.Controllers.HomeController
App.Web.Areas.Mobile.Controllers.HomeController
I've setup a default namespace for my HomeController in Global.ascx.cs:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new string[] { "App.Web.Controllers.HomeController" }
);
(Verified that App.Web.Controllers.HomeController is not a typo).
And also registered the Mobile's HomeController in MobileAreaRegistration:
public override void RegisterArea(AreaRegistrationContext context) {
context.MapRoute(
"Mobile_default",
"Mobile/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Therefore, why is it that I still see the error message? I've built/cleaned and ran again. Still the same outcome.
This is how I register my routes:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
In your Global.asax route registration for obvious reasons replace:
new string[] { "App.Web.Controllers.HomeController" }
with:
new string[] { "App.Web.Controllers" }
That's a namespace constraint that you should use there, not a specific type.

Resources