1

I'm looking at implementing an option for defining specific URL patterns that my HttpModule is to ignore.

I'm wanting to be able to define "filters" such as:

/Admin/{*}
/Products/{*}/Search

Which should filter out urls like:

http://mysite.com/admin/options
http://mysite.com/products/toys/search

but not filter out http://mysite.com/orders http://mysite.com/products/view/1

Much the same as how ASP.NET MVC has registered routes which match a pattern. I've looked at the source code of Phil Haack's Route Debugger, thinking it might show me how the RouteBase.GetRouteData(..) works, however it just utilizes it.

I cannot seem to find any examples that show how this RouteBase.GetRouteData actually works (or find the actual source code for it).

If anyone can point me in the right direction for how this (or pattern matching) is normally implemented that would be great.

P.S: I already know I can use Regular expressions, but would like to have a very specific rule set.

Kyro
  • 748
  • 1
  • 12
  • 28

1 Answers1

1

Update

Since you want to write an HttpModule that very closely mimics the work System.Web.Routing does, then perhaps you should use ILSpy and reflect the assembly and see what it does?

Original Answer (retained for posterity)

It's not clear if you're talking about ASP.NET MVC or about Spring MVC or about Spring.NET's extensions to ASP.NET MVC. If it's the first or the third:

For your first example:

Admin/{*}

solution #1 below will address it. For your second example:

Products/{*}/Search, solution #2 will address it (if there's a need to validate or to actually have something valid there)

The two solutions are:

  1. Create routes that take in those parameters (but do nothing with them, or don't care about them)
  2. Create an ActionFilter that checks the request for those parameters (from the route) and then replaces them with what actually should be there.

Solution 1

In your routes section in the global.asax.cs:

routes.MapRoute("AdminAnything",
    "Admin/{*anything}",
    new { controller = admin, action = "Show" }
    );

This will cause the following URLs to resolve to the Show action in the Admin controller (thus ignoring the inputs as you desire):

Admin/Options  
Admin/Anything-I-Want-here

Solution 2

Now, the second one is trickier because you actually have something in between it.

Example input:

Product/{*}/Search  

You can write an ActionFilter that intercepts the request, looks at it, and replaces that value with whatever you want.

First, the necessary route:

routes.MapRoute("ProductSearch",
    "Products/{searchType}/Search,
    new { controller = "Products", action = "Search" }
    );

Then your controller action:

public ActionResult Search(string searchType)
{
    //do nothing with searchType here.
}

If you wanted to actually replace that with something, you could send in a hidden form field in your view and process that in the Actionfilter:

public class SearchValidationActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if(filterContext.ActionParameters.ContainsKey("searchType") && filterContext.HttpContext.Request.Headers["hiddenSearchType"].IsNotNullOrEmpty()))
        {
        var actualSearchType = filterContext.ActionParameters["hiddenSearchType"] as SearchType;
        var searchType = filterContext.ActionParameters["searchType"];
        if (actualSearchType != null)
        {
            if (searchType.IsNullOrEmpty())
        {
            filterContext.Result = new SearchRedirectResult(actualSearchType.Name);
        }
        else if (!actualSearchType.Name.Equals(searchType))
        {
            filterContext.Result = new SearchRedirectResult(actualSearchType.Name,);
        }
        }
    }
        base.OnActionExecuting(filterContext);
    }
}

Basically, Solution #2 takes in anything, and based on the hidden search type, passes that to the actual search type.

George Stocker
  • 57,289
  • 29
  • 176
  • 237
  • I know how to do all that, the problem is that I dont know how the ASP.NET MVC .GetRouteData(..) method works (i.e. what is its underlying source code) – Kyro Jul 22 '11 at 01:17
  • I dont want to utilize the .GetRouteData(..) method, I want to reproduce something similar (not the same). Because my module will work against any asp.net and it doesnt stop the route from being handled by the users code. It just stops my module from performing further actions with that request. – Kyro Jul 22 '11 at 01:23
  • @Kyro Can you help me understand why you need the implementation of GetRouteData, and why the solution I posted won't work for you? Why an HttpModule for an ASP.NET MVC application? Can you go into more detail about your use case? – George Stocker Jul 22 '11 at 01:45
  • First off this is an HttpModule that tracks requests, it is designed to be a "drop into bin and change web.config". (if you know of ELMAH then its the same kind of drop & go style). Hence why we don't want the end users to have to write any code at all to get this to work. The reason why I asked about RouteBase.GetRouteData(..) is because it implements similar functionality we would like. Which is add filters, on each request go through the filters and pass the current HttpContext to each filters Test method and if it returns something then we break out and not include that request. – Kyro Jul 22 '11 at 05:38
  • @Kyro I've updated my answer. Simply, you should use ILSpy to reflect the `System.Web.Routing` assembly and mimic the functionality you need in your HttpModule. – George Stocker Jul 22 '11 at 13:27