How does RouteBase.GetRouteData work or pointers for implementing pattern matching
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:
/Ad开发者_如何学JAVAmin/{*}
/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.
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:
- Create routes that take in those parameters (but do nothing with them, or don't care about them)
- 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.
精彩评论