June 2008 - Posts

NHibernate 2.0 beta 1 is out
Sun, Jun 29 2008 23:15

The Rhino mocks post is still fresh and we've  already got a new release of another cool tool: NHibernate 2.0 beta 1 is out.

by luisabreu | with no comments
Filed under:
Rhino mocks 3.5 is out
Sun, Jun 29 2008 22:18

Download the bits and check the docs.

by luisabreu | with no comments
Filed under:
One year older
Fri, Jun 27 2008 10:12

Happy birthday to me :)

“New year’s” objective: blog more often :) Let’s see how it goes.

by luisabreu | 2 comment(s)
Filed under:
P/Invoke Interop Assistant
Thu, Jun 26 2008 22:07

Since today I'm putting my blog reading in day, here's another post announcing what seems to be a great tool: P/Invoke Interop Assistant.

by luisabreu | with no comments
Filed under:
MSDN low band rendering
Thu, Jun 26 2008 22:05

If like me you use the online help, then you've surely noticed several changes in these last months (ex.: friendly urls with support for namespaces, classes, properties, methods, etc). I've just seen in Craig's blog that now you can ask for a "low-bandwith page". Ok, you'll only believe it after seeing, so you should try loading this page for yourself.

by luisabreu | with no comments
Filed under:
How a geek changed the world
Mon, Jun 23 2008 22:20

A very good documentary by BBC which you can watch in YouTube:

by luisabreu | 1 comment(s)
Filed under:
Herb Sutter talk on machine arquitecture
Sun, Jun 22 2008 19:36

I'm still watching Herb Sutter's presentation on Machine Architecture, but I can already guarantee you that this is a must watch talk!

by luisabreu | with no comments
Filed under:
The C# compiler is really smart, but…
Fri, Jun 20 2008 11:37

I’m still not understanding why it won’t give me a warning when I create an internal class with a public method. Here’s an example:

class MyInternalClass{
   public void Test(){} //no compiler warning
}

Ok, at the end of the day, Test is really an “internal” method since the acessibility of a member can never be greater than the one of its containing type. But why can’t I get at least a warning? In this case, setting the method type to internal should be the “maximum” accesibility,right? There are other similar scenarios where we get the correct response from the compiler. For instance, you cannot declare a protected method on a struct. This makes sense, of course, because you can not inherit from a struct (therefore, you really don’t need to declare protected methods).

So, here we are: on the one hand, the compiler will let me declare a method as public on an internal class, even though that method will only end up beeing used on the assembly where it is defined due to the accessibility of its containing type without even generating a warning. On the other hand, the compiler won’t “relax” the protected method error on a struct type.

I’m not a compiler geek (or even a C# language expert) so the problem might really be on spec and not on the compiler. Anyway, I think that the compiler could at least generate a warning on these scenarios (internal classes with public methods). And what do you think?

by luisabreu | 5 comment(s)
Filed under:
Using routing with ASP.NET web forms apps
Fri, Jun 20 2008 10:50

In the previous posts, we’ve explored the internals of the routing assembly. If you’ve downloaded the ASP.NET MVC preview 3 from codeplex, then you’ll find an interesting sample on how to reuse the routing assembly with a ASP.NET web forms app.

If you’ve read the previous posts on the series, then you should know that a route is always associated with an IRouteHandler object which is responsible for returning the IHttpHandler that will handle the current request. The WebFormRouting assembly introduces several elements that you may reuse in your own web forms apps if you want to use the new routing features.

The IRoutablePage interface is added to the project to let you get access to the RequestContext generated internally by the routing assembly. This interface expands the IHttpHandler interface and adds a single property, called RequestContext, that will let you access the current RequestContext (RequestContext is an abstraction introduced by the abstractions assembly that ends up wrapping the current HTTP context).

Besides the interface, the WebFormRouting assembly will also add an existing RoutablePage class, which extends the Page class and implements the IRoutablePage interface. Besides that, it will also add a read only RouteData property that returns the RouteData associated with the current request.

There’s  also one more important class introduced by the WebFormRouting assembly: the WebFormRouteHandler class. This class implements the IRouteHandler interface and you should associate it to a route when building web forms apps that use routing. The coolest thing about this class is that you can configure it to perform security checks on the requested url. When you enable security checks, you’ll end up using the AutorizationModule.CheckUrlAccessForPrincipal method for performing those verifications.

Finally, it’s also important to mention that the WebFormRouting assembly introduces several extension methods to the RouteCollection class that will reduce the code you need to write for entering new routes on a web forms app that reuses these classes.

Now that you’ve got a general idea on what the WebForRouting assembly does, you shouldn’t really have any difficulties understanding the WebFormRoutingDemoWebApp that comes with the futures sample. On the Global.asax file you’ll find several routes definitions. Here’s one:

routes.Map("Secret", "BackDoor").To("~/Admin/SecretPage.aspx", false);

In this case, the Backdoor url is being mapped to the ~/Admin/SecretPage.aspx and you’re not using security checks to see if the current user can access the resource (notice the false value beeing passed to the To extension method introduced by the WebFormRouting assembly).

If you look at all the pages, you’ll notice that most of them are just normal pages. If you need to get access to the current url parameter values, then you should inherit from RoutablePage instead of the traditional Page class. I believe that the only page that does that is the default.aspx page.

And that’s it! Integrating the new routing framework with a web app is as easy as reusing the WebFormRouting assembly! I only wished having this assembly a year and a half ago, when I had to implement url rewriting on one of the last web apps I developed…

On the next posts, I’ll start looking at the MVC framework. Keep tuned!

by luisabreu | 1 comment(s)
Filed under: ,
Book review: The Pragmatic Programmer
Mon, Jun 16 2008 14:51

Yesterday I’ve finished reading The Pragamatic Programmer: from Journeyman to Master for the second time. I’ve bought this book 7 years ago (that is, in late 2001) and it was one of my first Amazon’s buys. It’s funny, but when I’ve started reading it again last week, I imediatelly recalled the experience I had when I first read the book. I can only say good things about this book. This book is already a classic! It’s one of those books that doesn’t get old! What else can I say?

I believe that the only thing I’d change is its title: I’m assuming that Pragmatic Developer is a much better title than Pragmatic Programmer. Anyway, the only thin I can say about this book is that if you still haven’t read it, then do yourself a favour and go read it. Final note: the guys that have written the book have a site where you can find more titles on the pragmatic series. Score for this book: 9/10.

by luisabreu | with no comments
Filed under:
The MVC routing assembly – part VI
Mon, Jun 16 2008 14:42

Today we’re going to discuss url partitioning. What’s url partioning? Well, I’m sure that you agree with me when I say that one of the greatest things about the routing assembly is that we can define parameters (or placeholders) on routes? Here’s an example that will surelly refresh your memory:

http://yoursite/{anything}

In the previous example, anything is an url placeholder. As we’ve seen, these placeholders are normally called url parameters and they will be replaced by specific values defined by the urls you use. In fact, you can even set default values and constraints on those parameters.

In the last post of the series, we’ve seen that the routing module (UrlRoutingModule) is responsible for intercepting the request and redirect it to the correct handler. At the time, I’ve said that:

Currently, the module handles two application events: the PostResolveRequestCache and the PostMapRequestHandler events. Most of the work is done on the PostResolveRequestCache. During that event, the module will use the RouteTable (more info about this object can be found on my previous post) object to get a route that matches the current request’s url.

When that happens, the module receives a valid RouteData instance (ie, a non-null RouteData instance). This object has all the necessary info about the current route.

What we didn’t see is how the current url’s request is mapped on a specific route that has been added to the routing table. That’s what we’ll see today!

Internally, the url patterns associated with a route is always partitioned in one or more elements of type PathSegment (btw, this is an internal class, so you won’t be able to use it in your code). Currently, there are two types of PathSegments: ContentPathSegments and SeparatorPathSegments.

SeparatorPathSegments are just that: elements that reprensent char / defined on a url (in the current release, you can only represent separators through / chars). ContentPathSegment elements represent all the other elements you can have in a url. These elements may have several PathSubSegment elements. Interestingly, there’s also two types of PathSubSegments: LiteralSubsegments and ParameterSubsegments.

LiteralSubsegments represent constant values defined on an url pattern associated with a route. On the other hand, ParameterSubsegments represent the url parameters. The following figure tries to show these relations.

pathsegments

Whenever we set the Url of a route object, we end up partitioning the string in several elements of the previous type. The partitioned url is kept by each Route object on a private instance of type ParsedRoute. The ParsedRoute.Parse method is responsible for kicking off the parsing of the url.

The first thing the method does is break the current url in several PathSegments elements. This initial partitioning uses the / char as a separator. In practice, this means that the strings delimited between each /pair will be represented by a ContentPath Segment element and that the separator char (/) will be represented by a SeparatorPathSegement element.

Notice that ContentPathSegment elements do require more processing than SeparatorPathSegment elements. We have 2 basics scenarios: each content segment may contain a constant value or a parameter value (keep in mind that we may have combinations of these elements in a content path, ie, a path may have several constant sub-segments or a mixed collection of constant and parameter sug-segments– more info on this on the next paragraphs).

When the parser finds a constant value, it will simply add an element of type LiteralSubsegment for that value. On the other hand, parameters will always be represented by ParameterSubsegment elements. Some examples will surelly help you understand the internal representation of these paths.

Example 1: Home/{whatever}

In this case, we’ll have 3 path segments: one for the separator char (represented by a single SeparatorPathSegment object) and two of type ContentPathSegment. The first, will have a single sub-segment path element, represented by an object of type LiteralSubsegment (this object will save the value Home in the Literal property of that class).

The second ContentPathSegment will also have one sub-segment, but in this case, we’ll get an element of type ParameterSubsegment. Besides saving the name of the parameter, this class has another property called IsCatchAll, which is true when we have a catch all parameter (read more about catch all parameters here).

Example 2: Home/{language}-{local}

In this example, we end up with 3 path segments: The first two are the same as the ones we’ve got on the previous example. The last one is also a ContentPathSegment, but in this case, we’ll end up with 3 sub-paths segments! The first and the third are ParameterSubsegments (parameters language and local). The second one is a LiteralSubsegment that will keep the ‘–’ literal value.

I really hope that the previous example have made the url parsing clear. In the previous example, we’ve never defined a catch all parameter. Here’s an example of a catch all parameter:

Home/{*whatever}

As you might recall, catch all parameters will match whatever url you pass in that are compatible with the “constant part” of the url pattern. When you partition the previous url in path segments, you’ll get a similar result to the one you got with example 1. The main difference is that in this case, you’ll have a catch all ParameterSubsegment (ie, the IsCatchAll property of the ParameterSubsegment object is set to true)!

Now that you understand url partitioning, it’s time to see how the UrlRoutingModule uses this info to decide if the current request is a routing request. Btw, I’m defining a routing request as a request that is intercepeted by the UrlModule module (and this will only happen when the module gets a valid RouteData object).

In the previous post, we’ve seen that UrlRoutingModule gets the current RouteData by calling the GetRouteData method over the internal route collection kept by the RouteTable object (in practice, this means that we go through all the Route objects and invoke the GetRouteData over each one of them).

This call is suficiently interesting for deserving a couple of paragraphs. The first thing this method (we’re still speaking about the GetRouteData method defined by the RouteCollection class) does is check the RouteExistingFiles property. When this property is set to false and the requested file exists on disk, the Route object doesn’t return a valid RouteData object (so, you’ll end up getting that file because the request won’t be intercepted by the UrlRoutingModule, leaving it to be processed by the default handler).

When this property is set to true (the default), you’ll end up getting routing even when there’s a physical file with the same url as the one requested (we’re assuming that the url pattern matches the current request’s url!).

As you might expect by now, getting a valid RouteData objects depends on the partitioning we’ve described in the previous paragraphs. The first thing the Route.GetRouteData method does is get a RouteValueDictionary with the values associated with the current request’s url. It will only return a valid dictionary (ie, non null value) when all the path segments are matched by values defined on the current url. It’s important to notice that the parameter values found on this dictionary may come from the current request’s url or from the default values you’ve set up on the route. So, what really matters is that the current url + defaults you’ve set up when you created the route cover all the url parameters.

The next step is performing constraint validation. As you might recall, you can apply constraints to the parameters defined on a route’s url. If all the constraints are ok, you’ll end up getting a valid RouteData object. At this time, it’s important to notice that the Values property of this object is built by copying the values maintained on the RouteValueDictionary that was built at the beginning of the Route.GetRouteData method (We’ve talked about this in the previous paragraph). The same thing happens to the DataTokens property: the value present on the RouteData object are copied from the ones defined on the Route.DataTokens collection.

By now you must have a good idea of how routing works. I’ll keep looking at the new MVC framework, so I believe that in the next days I’ll keep adding more posts on  this topic. Keep tuned!

by luisabreu | 2 comment(s)
Filed under: ,
The MVC routing assembly – part V
Fri, Jun 13 2008 10:55

Today we’re going to talk about one of the most important components of the System.Web.Routing assembly: the UrlRouting module. If you want to use the routing framework in your web applications, then you need to register this module on your web.config file (of course, after adding a reference to the routing assembly in your web app). This means that you’ll need to do register the module on your web.config file:

<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

The place where you put the previous line depends on the version of IIS you’re using. If you’re using IIS 6, then you’ll need to put it inside the system.web/httpModules section. On the other hand, if you’re using IIS 7, then just put it inside the  system.webServer/modules section.

Now that you’ve set up your app to use the routing module, lets see what it does. Currently, the module handles two application events: the PostResolveRequestCache and the PostMapRequestHandler events. Most of the work is done on the PostResolveRequestCache. During that event, the module will use the RouteTable (more info about this object can be found on my previous post) object to get a route that matches the current request’s url.

When that happens, the module receives a valid RouteData instance (ie, a non-null RouteData instance). This object has all the necessary info about the current route.The most important info is (arguably) the IRouteHandler instance that will be responsible for getting the HTTP handler that will return a response to the client. Interestingly, the routing assembly introduces only one IRouteHandler type: the StopRoutingHandler.

Whenever the module encounters a StopRoutingHandler, it knows it should simply do…nothing. On the other hand, if it finds a non-StopRoutingHandler, it will start by creating a new RequestContext (fed with the current HTTP context and with the previously obtained RouteData instance). Then it will get the HTTP handler responsible for processing the request by calling the IRouteHandler.GetHttpHandler method.

Finally, the module ends up creating a new RequestData instance (used for storing the current request’s url and HTTP handler) and putting it on the Items collection (available on the current HTTP context).

During the PostMapRequestHandler event, the module tries to recover the RequestData previously stored. If it finds it, then it will use the HTTP handler presented on the RequestData to set up the Handler property of the current HTTP context.

And that’s it! As you can see, the module doesn’t really do anything fancy. Most of the work depends on getting a valid route that matches the current request. I believe that its’s fair to say that getting a match is more interesting than the work that is done after finding a route. So, on the next post, we’ll talk about the matching algorythm used internally to see if the current url matches any of the pre-registered routes. Keep tuned.

by luisabreu | with no comments
Filed under: ,
S#arp Architecture updated
Wed, Jun 11 2008 22:44

Billy has just updated this cool demo. Check it out at codeplex.

by luisabreu | with no comments
Filed under:
One more thing about the RouteTable...
Wed, Jun 11 2008 22:42

In my last post on this series, we've seen how we can use the RouteTable class to register all the routes available on a web application. I'd just like to add one more thing on the locking topic. As you might recall, we've seen that internally the RouteCollection uses locks to guarantee that everything works well in multithreaded scenarios.

At that previous post, I've written that:

Besides these methods, the class introduces some utility methods that will let you control the lock in the collection. I’m talking about the GetReadLock and GetWriterLock methods. These methods are used internally to garantee that the route collection plays well in  muthithreaded scenarios. Since these methods are public, this means that you should call them if you decide to go through all the routes stored on a collection by using a foreach loop. Notice that you don’t need to do that if you use the methods presented in the previous list since those methods already take the appropriate locks.

Well, this is true, but not in all the cases. If you look at the RouteCollection's insertion/deletion methods (Add, InsertItem and RemoveItem), you'll see that none of them uses a lock. Why? Well, because normally you'll add your routes during the application start event (as I've said in my previous post) and in these scenarios you don't need to lock anything because you know that at that time there's only  a single thread. On the other hand, if you need to add/remove routes after that event, then you'll need to get a lock by calling the GetWriterLock method (btw, don't forget to dispose it when you don't need it!).

Special thanks go to Eilon for letting me know this.

by luisabreu | with no comments
Filed under: ,
The "new" offside rule
Wed, Jun 11 2008 22:30

This is a post on football (no, I'm not talking about American football - man, how can you call that football? you play it with your hands :) I'm talking about soccer). So, if you don't like, just don't read it :)

If, like me, you're a fan, then you surely know that Euro 2008 is happening on Austria and Switzerland. Btw, Portugal has already qualified for the next round! hurray!

Ok, the objective of this post is to try to argue against this. It's interesting to see that UEFA always tries to prevent us from seeing that their referees simply screw up sometimes (yep, like everyone else!). Ok, let's see what Mr. David Taylor says about the offside goal scored by Netherlands:

 

I would like to take the opportunity to explain and emphasise that the goal was correctly awarded by the referee team," he said. "I think there's a lack of understanding among the general football public, and I think it's understandable because this was an unusual situation. The player was not offside, because, in addition to the Italian goalkeeper, there was another Italian player in front of the goalscorer. Even though that other Italian player at the time had actually fallen off the pitch, his position was still relevant for the purposes of the offside law."

Well well...It happens that the Italian player got injured after a clash with his goal keeper and was out of the field! I think that out is the important thing here! If he's out, injuried, then he surely isn't between the goal line and Nisterlrooy, right?

Interestingly, if you read the rules, you'll see that there is no special case there for these scenarios. In fact, if you look at the videos available on the FIFA web site, you'll quickly see that the offline position is delimited by the goal line! And that's it. If the injured guy laying down outside the pitch is enough for not making Nistelrooy offside, then I really can't read English...

by luisabreu | 3 comment(s)
Filed under:
Book review: ADO.NET 3.5 Cookbook
Wed, Jun 11 2008 11:33

[Disclaimer: I’ve received a free copy of this book for review]

After several days, I’ve finally finished reading this book. This is really a very complete book wit lots and lots (and lots!) of examples. It’s fair to say that it covers most (if not all) ADO.NET related scenarios (I’m an SQL Server user but if you’re into Oracle then it also has several examples that show how to use ADO.NET and Oracle).

I do have one complaint though: chapter 8. Currently, I’ll personally “hurt” anyone that is working on the same project as me and that uses ADO.NET objects on window forms or ASP.NET front ents! Ok, I’m not violent, so I wouldn’t really hurt anyone :) serioulsy, don’t use ADO.NET objects on your UI.

Having said this, I still recommend it (if you’re working with ADO.NET) and I’m going to give it 7.5/10.

by luisabreu | 2 comment(s)
Filed under:
Resharper 4.0 is out!
Tue, Jun 10 2008 11:52

Finally!

by luisabreu | with no comments
Filed under: ,
The MVC routing assembly – part IV
Mon, Jun 9 2008 15:00

In the previous posts, we’ve talked about Routes. Today, we’re see how we can register the routes on a ASP.NET web application.

Currently, a colecction of routes is represented through an element of type RouteCollection. If you fire up Reflector and start looking at this class, you’ll see that a RouteCollection is just a specialized version of the Collection<RouteBase> type.

In fact, if you take a closer look at the class, you’ll see that it just ends up adding a couple of methods and then it will simply override others inherited from the base class. Here’s a list of the new methods that have been added:

  • GetRouteData: you can use this method to get a reference to a RouteData element associated with the current context. Internally, the method goes over all the routes maintained in its internall collection, calling the GetRouteData over each of those instances. When it finds a valid route (ie, when one of those methods returns a non-null value), it simply returns that value;
  • GetVirtualPath: as you might expect by now, this method will return the Virtual Path associated with the current request (when one is available). Internally, it does a similar job tothe GetRouteData method; the only differente is that it will call the GetVirtualPath method over each registered route (instead of the GetRouteData method);
  • Add: the class introduces an overload of the Add method. Instead of simply receiving a route, with this class you’ll be able to associate a name with a specific route. When you use this method, you end up saving a reference to the route on the internal collection maintained by the base class and you’ll also save a reference to that element on a dictionary defined by the RouteCollection class. In practice, this means that you can also get a route by name quickly.

Besides these methods, the class introduces some utility methods that will let you control the lock in the collection. I’m talking about the GetReadLock and GetWriterLock methods. These methods are used internally to garantee that the route collection plays well in  muthithreaded scenarios. Since these methods are public, this means that you should call them if you decide to go through all the routes stored on a collection by using a foreach loop. Notice that you don’t need to do that if you use the methods presented in the previous list since those methods already take the appropriate locks. You can read more about the locking mechanism on Eilon’s blog.

Ok, now that we know how to store several routes, we need to talk about how to add a collection of routes to a web app. In the current release, you add routes by accessing the static Routes property exposed by the RouteTable class. Generally, you’ll add routes during the application start event. Here’s a quick example:

RouteTable.Routes.Add( “route1”,
       new Route( “foo/{anything}”, new MvcRouteHandler() ) );
RouteTable.Routes.Add( “route2”,
       new Route( “foo/{lang}-{locale}/{anything}”, new MvcRouteHandler() )
);

Notice that I’m not setting any defaults or constraints on the previous Routes (though I could have done that).

If you’re using the the MVC platform, then you’ll be glad to know that the System.Web.Mvc assembly introduces several extension methods that will reduce the code necessary to add Routes to the RouteTable. After adding the correct namespace:

using System.Web.Mvc;

you’ll be able to access the following extension methods:

public static class RouteCollectionExtensions
{
    public static void MapRoute(this RouteCollection routes, string name, string url);
    public static void MapRoute(this RouteCollection routes, string name, string url, object defaults);
    public static void MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints);
}

In practice, this means that you can write the previous rules like this:

RouteTable.Routes.MapRoute( “route1”, “foo/{anything}” );
RouteTable.Routes.MapRoute( “route1”, “foo/{lang-locale}/{anything}” );

Internally, those methods will end up creating the routes and associating them with the MvcRoutingHandler (which, as we’ll see in a future post, is responsible for getting the correct handler for MVC requests). Notice that there are also other overloads that will let you sepcify the defaults and the constraints applied to a specific route, as you can see by looking at the previous extension methods’ signatures.  

In the next post we’ll see how these routes are processed and we’ll talk about the UrlRouting module. Stay tunned.

by luisabreu | with no comments
Filed under: ,
The MVC routing assembly – part III
Mon, Jun 9 2008 14:09

In the last post, we’ve talked about several of the properties exposed by the Route class. Unfortunately, the post grew beyond my initial expectations, which meant that the writing time was exceeded before completing the analysis of this class.

Today we’ll cover its last important feature: constraints. When a route is associated with a pattern url, you can also set up several constraints and apply them to any of the parameters defined on those urls. The constraints follow the same approach as the one used by the Defaults property: you need to pass a dictionary where each constraint is identified by the parameter name and its value (ie, the constraint) is defined through an object.

Currently, you have two options: a constraint can be defined through a regular express or through an object that implements the IRouteConstraint. Before presenting examples of how you can define constraints, it’s important to know when they’ll be evaluated.

In the latest release, constraints are always evaluated when you call the GetRouteData and the GetVirtualPath methods defined by the Route class. Internally, the class will always start by trying to convert an existing constraint to an element of type IRouteConstraint. When that conversion is possible, the Route class ends up calling the Match method (which is the only method introduced by the URouteConstraint interface) over that instance; when that conversion isn’t possible, the Route class tries to convert the dictionary entry to a string and then uses a regular expression to see if the parameter is valid.

Lets run some tests to see how this works. We’ll start with the regular expression approach…Let’s suppose that we have the following pattern:

forms/{language}-{locale}/somepage

And we want to make sure that the parameters language and locale have exactly 2 chars each. With constraints, you can achieve this by using the following route:

var route =

new Route("forms/{language}-{locale}/somepage",
                                 new RouteValueDictionary(), //defaults
                                 new RouteValueDictionary(new { language = "\\w{2}", locale = "\\w{2}" }), //constraints
                                 new MvcRouteHandler() );

With the previous rule, you’ll get a not found exception if any of the language or locale parameters don’t match the predefined rules (which in this case, means you’ll need two chars – ok, numbers shouldn’t be accepted but this is only demo code). Notice that you don’t need to set use the ^and $ to delimit the regular expression: those chars are automatically appended to the expression before it is applied to the parameter.

If you need more control than the one you get from regular expressions, then you can implement the IRouteConstraint interface. Currently, this interface has the following members:

public interface IRouteConstraint
{
    bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection);
}

The Match method will be called to perform the validation. When that happens, it receives a reference to the current context, a reference to the current route, the name of the parameter, a dictionary  with a list of parameters and its current values and a value from the enumeration RouteDirection which indicates the current action.

When this last parameter has its value set to RouteDirection.IncomingRequest, it means that the validation is being called from the Route.GetRouteData instance method. On the other hand, when it’s set to RouteDirection.UrlGeneration means that validation is being started from the Route.GetVirtualPath instance method (in practice this means that you can validate your method by using different strategies depending on the context of the call).

In the current release, the routing assembly has only a predefined route constraint called HttpMethodConstraint. Its main objective is to let you define the type of HTTP calls that are allowed. For instance, the following code will only allow POST HTTP calls:

new Route("forms/{language}-{locale}/somepage",
                                 new RouteValueDictionary(), //defaults
                                 new RouteValueDictionary(new { httpMethod= new HttpMethodConstraint( “POST”) }), //constraints
                                 new MvcRouteHandler() );

Notice the parameter name…in this case, you’re not really interested in applying a constraint to one of the url parameters. So, it’s safe to call it httpMethod, even though there really isn’t any parameter called with that name. Btw, it’s also important to mention that the constructor of this class accepts a variable number of parameters (we’re talking about a params parameter here!). So, nothing prevents you from passing several types of HTTP methods to its constructor.

And that’s it. On the next post we’ll talk about the routing table. Keep tuned.

by luisabreu | with no comments
Filed under: ,
SQL Server 2008 RC0 available for MSDN subscribers
Fri, Jun 6 2008 23:58

Via Wally.

by luisabreu | with no comments
Filed under:
More Posts Next page »