Dipal Mehta
Dipal Mehta

Reputation: 462

MVC custom routing with validation

Masters,

In my project I have specified many different routes something like follows.

routes.MapRoute(
   name: "StudentMerit", 
   url: "Student-Merit", 
   defaults: new { controller = "StudentMerit", action = "GetData"});

routes.MapRoute(
   name: "StudentResults", 
   url: "Student-Results", 
   defaults: new { controller = "StudentResults", action = "GetData"});

As you can see url is hyphen separated and i am not much worried about action name

All this routes can be rewritten if i can tell MVC that Replace Hyphen with nothing in URL and it will be my controller.

Something like,

routes.MapRoute(
   name: "AllInOne", 
   url: "{Cont-roller}", 
   defaults: new { controller = {Cont-roller}.replace("-",""), action = "GetData"});

Is there any way to do this? Please help.

Thanks in advance.

Upvotes: 2

Views: 1525

Answers (1)

LostInComputer
LostInComputer

Reputation: 15420

Create your own RouteHandler. I don't know if this is the best solution though.

public class RemoveDashRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        requestContext.RouteData.Values["controller"] = ((string)requestContext.RouteData.Values["controller"]).Replace("-", String.Empty);

        return base.GetHttpHandler(requestContext);
    }
}

Usage

routes.MapRoute(
     name: "AllInOne",
     url: "{controller}",
     defaults: new { controller = "Default", action = "GetData" }
).RouteHandler = new RemoveDashRouteHandler();

Edit for alternative solution

I found a better solution (in my opinion) by sub-classing Route then overriding GetRouteData. It's better since Route's responsibility is to generate the RouteData while MvcRouteHandler's responsibility is to get the IHttpHandler.

public class RemoveDashRoute : Route
{
    private const string ControllerKey = "controller";

    public RemoveDashRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints = null, RouteValueDictionary dataTokens = null, IRouteHandler routeHandler = null)
        : base(url, defaults, constraints ?? new RouteValueDictionary(), dataTokens ?? new RouteValueDictionary(), routeHandler ?? new MvcRouteHandler())
    {
    }
    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var routeData = base.GetRouteData(httpContext);
        if (routeData != null && routeData.Values.ContainsKey(ControllerKey))
        {
            routeData.Values[ControllerKey] = ((string)routeData.Values[ControllerKey]).Replace("-", String.Empty);
        }
        return routeData;
    }
}

Usage

routes.Add("AllInOne", new RemoveDashRoute(
    url: "{controller}",
    defaults: new RouteValueDictionary(new { controller = "Home", action = "GetData" }))
);

Upvotes: 4

Related Questions