Wednesday, December 26, 2012

Implement GetHashCode() to track changed objects in C#

Let's say we pull information about Movies from remote XML and save it in our database. Class that represent this objects can look like:
 public class Movie  
 {  
     public int Id { get; set; }  
     public string Name { get; set; }      
     public int? Duration { get; set; }  
     public int? Director { get; set; }      
     public int[] Actors { get; set; }      
     public int[] Genres { get; set; }      
     public int[] Countries { get; set; }      
     public string PosterUrl { get; set; }  
     public double? Rate { get; set; }  
     public int? Votes { get; set; }  
     public double? Imdb { get; set; }  
     public int? ImdbVotes { get; set; }  
     public string Site { get; set; }  
     public string Limits { get; set; }  
     public DateTime? Date { get; set; }  
     public string Description { get; set; }  
     public string Trailers { get; set; }  
     public string Company { get; set; }      
 }  

Write operations are expensive if there are a lot of objects to be saved, so for performance reasons we should NOT save new object in database, if there is old object in database that is the same. So we need to extract object from databse and determine if new object differ from the old one. If objects are the same we DO NOT update it.

But how to determine that objects are the same?

Objects are differ if their contents differ. In our case we can clarify this as follows: Objects are differ if their properties are differ.

Let's override GetHashCode() and Equals() methods to define how to check equality of 2 Movie objects:
 public class Movie  
 {  
    public int Id { get; set; }  
    public string Name { get; set; }  
    public int? Duration { get; set; }  
    public int? Director { get; set; }  
    public int[] Actors { get; set; }  
    public int[] Genres { get; set; }  
    public int[] Countries { get; set; }  
    public string PosterUrl { get; set; }  
    public double? Rate { get; set; }  
    public int? Votes { get; set; }  
    public double? Imdb { get; set; }  
    public int? ImdbVotes { get; set; }  
    public string Site { get; set; }  
    public string Limits { get; set; }  
    public DateTime? Date { get; set; }  
    public string Description { get; set; }  
    public string Trailers { get; set; }  
    public string Company { get; set; }  
    
    public override int GetHashCode()  
    {  
       return HashCodeGenerator.Generate(Id, Name, Duration, Director, Actors, Genres, Countries, PosterUrl, Rate, Votes, Imdb, ImdbVotes, Site, Limits, Date, Description, Trailers, Company);  
    }  
    public override bool Equals(object obj)  
    {  
       return this.GetHashCode() == obj.GetHashCode();  
    }        
  }  

As you can see, we use custom class HashCodeGenerator to generate hash code from specified property values that we need to track.

Implementation of this class:
  public static class HashCodeGenerator  
  {  
     public static int Generate(params object[] objects)  
     {  
       unchecked  
       {  
         var offset = 13;  
         var compositionOffset = 7;  
         foreach (object obj in objects)  
         {  
           if (obj==null)  
             continue;  
           if (obj is Array)  
           {  
             var array = obj as Array;  
             foreach (var item in array)  
             {  
               offset = (offset * compositionOffset) + item.GetHashCode();  
             }  
           }  
           else  
           {  
             offset = (offset * compositionOffset) + obj.GetHashCode();  
           }            
         }            
         return offset;  
       }  
     }      
   }  

Wednesday, December 19, 2012

Using expression trees to get rid of "magic" strings in C#

"Magic" strings may appear in programming code in many cases. For example, if we need to pass property names to some method.

Let's say we need to make DatabaseIndexCreator class that creates database index for specified property name(or properties, if index is compound) of some model(in our example it's Person class):
 public class Person  
 {  
   public string Name { get; set; }  
   public string Surname { get; set; }  
   public bool Sex { get; set; }  
 }  

So, we end up with function that accept property names as strings:
 public class DatabaseIndexCreator<TEntity>  
 {  
   public void CreateIndex(string[] fields)  
   {  
     //creating index  
   }  
 }  

And use this class like this:
 DatabaseIndexCreator<Person> indexCreator = new DatabaseIndexCreator<Person>();  
 //creating simple index:  
 indexCreator.CreateIndex(new[] { "Name" });  
 //creating compound index:  
 indexCreator.CreateIndex(new[] { "Name", "Sex" });  

It's bad design, because you can forget to rename this "magic" strings after renaming properties of Person class.

But you can use Expression Trees - nice C# feature to get rid of this "magic" strings in your code.

Let's create class with extension method for Expression<Func<T, U>> expression:
  public static class ExpressionEx  
  {  
     public static HashSet<string> AsMemberExpressionKeys<T, U>(this Expression<Func <T, U>> index)  
     {  
       var exp = index.Body as NewExpression;  
       var keys = new HashSet<string>();  
       if (exp != null)  
       {  
         foreach (var x in exp.Arguments.OfType<MemberExpression>())  
         {  
           keys.Add(GetPropertyAlias(x));  
         }  
       }  
       else if (index.Body is MemberExpression)  
       {  
         var me = index.Body as MemberExpression;  
         keys.Add(GetPropertyAlias(me));  
       }  
       return keys;  
     }  
     private static string GetPropertyAlias(MemberExpression mex)  
     {  
       var retval = "";  
       var parentEx = mex.Expression as MemberExpression;  
       if (parentEx != null)  
       {  
         retval += GetPropertyAlias(parentEx) + ".";  
       }        
       retval += mex.Member.Name;  
       return retval;  
     }  
  }  

What benefits can we get from this tricky extension method?

Now we can refactor our DatabaseIndexCreator class like this:
 public class DatabaseIndexCreator<TEntity>  
 {  
   public void CreateIndex<TReturn>(Expression<Func<TEntity, TReturn>> exp)  
   {  
     string[] fields = exp.AsMemberExpressionKeys().ToArray();  
     //creating index(simple or compound)  
   }  
 }  

And use this class like this:
 DatabaseIndexCreator<Person> indexCreator = new DatabaseIndexCreator<Person>();  
 //creating simple index:  
 indexCreator.CreateIndex(t => t.Name);  
 //creating compound index:  
 indexCreator.CreateIndex(t => new {t.Name, t.Sex});  

As you see, there is no more "magic" strings, that is very good for our code design and our nerves.

Wednesday, December 12, 2012

Redirect www subdomain to root domain in ASP.NET

Let's say we want to perform permanent redirect from http://www.example.com address to http://example.com in our ASP.NET application for SEO purposes(URL canonization).

First of all, we need to download Rewrite module for IIS7:
http://www.microsoft.com/web/gallery/install.aspx?appid=urlrewrite2

Then you need to open IIS Manager and navigate to URL Rewrite section.

After proper configuration in IIS Manager you'll get section in your Web.config that can look like:
 <configuration>  
   <system.webServer>  
     <rewrite>  
       <rules>  
         <rule name ="CanonicalHostNameRule" stopProcessing="true">  
           <match url="(.*)" />  
           <conditions>  
             <add input ="{HTTP_HOST}" pattern="^www\." negate="false" />  
           </conditions>  
           <action type ="Redirect" url="http://example.com/{R:1}" />  
         </rule>  
       </rules>  
     </rewrite>  
   </system.webServer>   
 </configuration>  

Thursday, December 6, 2012

Cancelable tasks in .NET 4.0

There is new nice feature in .NET >= 4.0 - cancelling asynchronoums tasks.


Now you can do this:
 public class JobClass  
   {      
     private readonly CancellationTokenSource _cancellationSource;  
     public JobClass()  
     {  
       _cancellationSource = new CancellationTokenSource();        
     }              
     public void DoWork()  
     {  
         ...  
         Action action = () =>  
          {             
            foreach (var a in array)  
            {               
             /*do something*/  
             _cancellationSource.Token.ThrowIfCancellationRequested();  
            }  
          };  
        var task = new Task(action, _cancellationSource.Token);  
        task.Start();         
     }  
     public void Cancel()  
     {  
       _cancellationSource.Cancel();  
     }                       
   }  

As you can see, we created Task with cancellation Token. After this we can use cancellationSource to cancel this Task any time we want. It should be noted, that we use Token.ThrowIfCancellationRequested() method in async method body to throw exception if cancellation was requested.

Thursday, November 29, 2012

Hybrid CQRS implementation using MongoDb

Introduction to CQRS

Command and Query Responsibility Segregation(CQRS) is a pattern that suggests you to use different models to read and to write information.

In standard relational systems you have dilemma: use normalized database or denormalized database? In first case you get fine-designed database that is good for writing data, but has poor reading performance. In second case you get headache with your updates, but(if properly denormalized) you can get good reading performance.

So, CQRS suggests to use 2 different databases: one optimized for reading(denormalized) and another for writing(normalized). It is a very tempting way to designing systems. The only big problem with this solution is that you need somehow to sync you databases. You can create some sort of Denormalizer that would perform synchronization between your normalized and denormalized databases, after writings to your normalized database.

Is there a simpler solution?
I think there is one using NoSQL database(for example, MongoDb).

What is MongoDb?

MongoDb is a non-relational data store for JSON documents. More about MongoDb.
Big benefit of MongoDb is that it you can easily store\restore objects that you have inside your program to\from database. This help us much in our Hybrid CQRS implementation.

Hybrid CQRS implementation using MongoDb
All commands(write operations) go through Service layer where validators and other protective measures are applied. Querying(read operations) are allowed directly from Database to speed up process.

Since we use NoSQL database(MongoDb) it is not strictly necessary for us to use different databases for reading and writing. If we make proper design of our MongoDb database, it will be good for reading(due to structure of data storage) and no bad for writings(if we do not go too far with denormalization).

This CQRS implementation is applicable in cases when you want to use Domain-Driven design approach for your system Core, at the same time retaining the ability for fast data reading for your Web application.

Tuesday, November 20, 2012

Elmah: filtering "spam" exceptions

Elmah is a great logging facility for ASP.NET.

It can be easily configured in Web.config. Here an example:
 <configuration>  
  <elmah>  
   <errorLog type ="Elmah.XmlFileErrorLog, Elmah" logPath ="~/errors/" />   
   <security allowRemoteAccess ="1" />   
   <errorMail from ="noreply@server.com" to= "admin@example.com" subject ="Web Exception" async= "true "smtpPort ="0"></errorMail>   
  </elmah>  
 </configuration>  

But it's very likely that you will get a lot of "spam" error messages in your log and on your e-mail. So you'll want to filter some of those messages.

You can do it in a very flexible way as follows:
 <configuration>  
  <elmah>  
   <errorLog type ="Elmah.XmlFileErrorLog, Elmah" logPath ="~/errors/" />  
   <errorFilter>  
    <test>  
     <or>  
      <equal binding ="HttpStatusCode" value ="404" type ="Int32" />  
      <regex binding ="Exception.Message" pattern =" ^A potentially dangerous Request$" />  
      <regex binding ="Exception.Message" pattern =" ^The parameters dictionary contains a null entry$" />  
      <and>  
       <regex binding ="Exception.Message "pattern ="^The operation has timed out$" />  
       <regex binding ="Context.Request.ServerVariables['URL']" pattern =".*/some-url/$" caseInsensitive="true" />  
      </and>  
      <and>  
       <regex binding ="Exception.Message" pattern ="^Invalid image profile*" />  
       <regex binding ="Context.Request.ServerVariables['HTTP_USER_AGENT']" pattern ="bot" />  
      </and>  
     </or>  
    </test>  
   </errorFilter>  
   <security allowRemoteAccess ="1" />  
   <errorMail from ="noreply@server.com" to= "admin@example.com" subject ="Web Exception" async= "true "smtpPort ="0"></errorMail>  
  </elmah>  
 </configuration>  

As you can see, we just added <errorFilter> section with various filter conditions, separated by Boolean operations(<or>, <and>). It is a very intuitive way to filter errors that you don't want to track down with Elmah.

Sunday, November 18, 2012

MongoDb for beginners


What is MongoDb?

MongoDb is a non-relational data store for JSON documents. By non-relational we mean that it does not store data in tables like relational databases does. It stores JSON documents.


What is JSON? JSON(JavaScript Object Notation) is a standard for representing data structures in a text-based human-readable form. JSON documents look like this:

{"Name" : "Bob"} 

This very simple JSON document has the key "Name" and the value "Bob". You can create more complex JSON documents with hierarchies:

{"Name" : "Bob", "Age" : 50, "Hobbies" : ["hockey", "football", "movies"], "Account" : {"Login" : "Bobby", "Password" : "12345"}}

JSON documents are stored within MongoDb collections(collections are analogous to tables in a relational database). It’s very useful when writing programs, because this type of data structures looks a lot closer to what you have inside your programs, than relational database does:
 class Person  
 {  
   public string Name;  
   public int Age;  
   public string[] Hobbies;  
   public AccountDetails Account;  
 }  
 class AccountDetails  
 {  
   public string Login;  
   public string Password;  
 }  

That’s new, because you never do that in relational table. The fact that MongoDb stores documents makes programming your domain model very convenient.

Schemaless 

Another interesting aspect about MongoDb is that it also schemaless. Schemaless means that two documents don’t need to have a same schema.

For example, you can store this documents inside the same collection:
{"a" : 1, "b" : 2}
{"a" : 1, "b" : 2, "c" : 3}

MongoDb vs Relational databases


The idea of MongoDb is to retain most of scalability and performance, giving you a lot of functionality to work with, but not quite as much as you can get in relational database management systems. 

That’s because there are few different things are missing in MongoDb:
  • Joins. MongoDb stores documents. Each document is stored in collection. But if you want to do a JOIN between two collections - you can’t do that in MongoDb. And the reason is that JOINs scale very poorly.
  • Transactions. That sound very bad, but the truth is that you don't need transactions in MongoDb in applications where you would need them in relational systems. And the reason is that documents are hierarchical in MongoDb and you can access those documents atomically. 
Choice between non-relational and relational data stores can't be easy. But if you want to create a scalable, high-performance application you should consider MongoDb as an option.

This article is based on video lectures from 10gen education course https://education.10gen.com.

Monday, November 12, 2012

SSO in multiple ASP.NET applications under the same domain

Suppose you have two different web applications under the same domain. For example:

First web application(ASP.NET Web Forms): http://example.com/
Second web application(ASP.NET MVC): http://example.com/admin/

Both web applications use ASP.NET Forms authentication.

How to make possible to authenticate in one web-application and be authenticated in another?

The answer is to use same machineKey configuration and authentication cookie name in both web applications.

Example of first web application(ASP.NET Web Forms) config section:
 <system.web>  
  <machineKey validationKey="6366D9EDF5591718A1A69557F106AFC16A8A184159028364814BD3B9D48941832E7310C0386DAD406AD04337B4B57D1772430233FCB82E265635DE5E35FF3C4F" decryptionKey="76D34CAEA4614B2EBFB0E20819CFE744389ADCC511D94C8CEA7DA6517C9D0E68" validation="SHA1" decryption="AES" />  
  <authentication mode ="Forms" >  
    <forms name =".AUTH" loginUrl= "~/Login.aspx" />  
   </authentication>   
 </system.web>  

Example of second web application(ASP.NET MVC) config section:
 <system.web>  
  <machineKey validationKey="6366D9EDF5591718A1A69557F106AFC16A8A184159028364814BD3B9D48941832E7310C0386DAD406AD04337B4B57D1772430233FCB82E265635DE5E35FF3C4F" decryptionKey="76D34CAEA4614B2EBFB0E20819CFE744389ADCC511D94C8CEA7DA6517C9D0E68" validation="SHA1" decryption="AES" />  
  <authentication mode ="Forms" >  
    <forms name =".AUTH" loginUrl= "~/Authentication/Login " />  
   </authentication>  
 </system.web>  

You can generate unique machineKey for your applications here: http://aspnetresources.com/tools/machineKey

Friday, November 9, 2012

Adding custom WCF endpoint behavior in client code

Endpoint behaviors are used to customize the runtime behavior of WCF clients. It's very useful, for example, if we want to send some special information to WCF service with each call from client.

Suppose, we have ASP.NET application and we need to send current user identity with every call to our IPersonalService.

First of all, we need to configure our WCF client. We use Castle Windsor WCF Facility to do this. In Application_Start handler of Global.asax we need to create WindsorContainer, add WcfFacility, and register our IPersonalService with custom SecureEndpointBehavior:

 Container = new WindsorContainer();  
 Container.AddFacility<WcfFacility>();  
 var personalServiceUrl = ConfigurationManager.AppSettings["PersonalServiceUrl"];  
 Container.Register(Component.For<IPersonalService>().AsWcfClient(WcfEndpoint.BoundTo(new BasicHttpBinding()).At(personalServiceUrl).AddExtensions(new SecureEndpointBehavior())));  

To create desired endpoint behavior we need to implement actually endpoint behavior and message inspector.

Example of endpoint behavior class:
 public class SecureEndpointBehavior : BehaviorExtensionElement ,IEndpointBehavior  
   {  
     public void Validate(ServiceEndpoint endpoint)  
     {  
     }  
     public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)  
     {  
     }  
     public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)  
     {  
     }  
     public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)  
     {  
       clientRuntime.MessageInspectors.Add(new SecureMessageInspector());  
     }  
     protected override object CreateBehavior()  
     {  
       return new SecureEndpointBehavior();  
     }  
     public override Type BehaviorType  
     {  
       get { return typeof(SecureEndpointBehavior); }  
     }  
   }  

Example of message inspector class:
 public class SecureMessageInspector : IClientMessageInspector  
   {          
     public object BeforeSendRequest(ref Message request, IClientChannel channel)  
     {        
       var siteUser = DependencyResolver.Current.GetService<ISiteUser>();  
       var header = new MessageHeader<Guid>(siteUser.UserId);  
       var untypedHeader = header.GetUntypedHeader("UserToken", "MyProject");  
       request.Headers.Add(untypedHeader);        
       return request;  
     }  
     [DebuggerStepThrough]  
     public void AfterReceiveReply(ref Message reply, object correlationState)  
     {  
     }  
   }  

As you can see, SecureEndpointBehavior class just adds SecureMessageInspector instance to list of run-time message inspectors. Our SecureMessageInspector is very simple: it just creates MessageHeader, puts siteUser.UserId into, and adds this header to the list of headers.

Now, on IPersonalService side you can retrieve user id under which the call was made to the service. In IPersonalService implementation, you can use the following command to retrieve user id:
 var userId = OperationContext.Current.IncomingMessageHeaders.GetHeader<Guid>("UserToken", "MyProject");  

Wednesday, November 7, 2012

Static polymorphism and dynamic keyword in C#

Static Polymorphism - is kind of polymorphism also known as function overloading(or operator overloading).

Static polymorphism means that functions can be applied to arguments of different types, different number and sequence of arguments.
The various types of parameters are specified at compile time, so the function can be bound to calls at compile time. This is called early binding.

Example of static polymorphism:
 class Program  
 {  
   class A { }   
   class B { }  
   private static void Foo(A a)   
   {   
     //something   
   }   
   private static void Foo(B b)   
   {   
     //something   
   }   
   static void Main(string[] args)  
   {   
     A a = new A();   
     Foo(a);   
     B b = new B();   
     Foo(b);   
   }  
 }  

In this example we exactly know the type of object(A or B) and corresponding Foo method that should be called.

Let's say we get object from the third-party method and we do not know exactly real type of the object(A or B). We can get this object and then cast reference to A(or to B) and call corresponding Foo method. Or we can use nifty dynamic keyword:
 public class ThirdPartyClass  
 {  
   public static IObject GetObject()  
   {  
     //something  
   }  
 }  
 class Program  
 {  
   class A { }   
   class B { }   
   private static void Foo(A a)   
   {   
     //something   
   }   
   private static void Foo(B b)   
   {   
     //something   
   }   
   static void Main(string[] args)   
   {   
     dynamic d = ThirdPartyClass.GetObject();  
     Foo(d);   
   }  
 }  

In this example, actual type of the variable d that’s declared dynamic is resolved at run time. If variable d is not of type A or B then exception will be thrown, because of trying to call method Foo with incompatible argument type.

Tuesday, November 6, 2012

Installing WCF-client using Castle Wcf Facility

Let's say we want to consume WCF-service in our ASP.NET MVC application. We try to keep clean design, and we want to inject our dependent WCF service, say, in our MVC Controller.

For example:
 public class MyController : Controller  
 {  
   private readonly IAnonymousService _anonymousService;  
   public MyController(IAnonymousService anonymousService)  
   {  
    _anonymousService = anonymousService;  
   }  
 }  

To accomplish this we need new version of Castle Windsor container. You need to create WindsorContainer, add Castle WCFWacility, and then register your service.

It may looks like this(in your Global.asax Application_Start handler):
 Container = new WindsorContainer();  
 Container.AddFacility<WcfFacility>();  
 var anonumousServiceUrl = ConfigurationManager.AppSettings["AnonymousServiceUrl"];  
 Container.Register(Component.For<IAnonymousService>().AsWcfClient(WcfEndpointBoundTo(new BasicHttpBinding()).At(anonumousServiceUrl)));  

Friday, November 2, 2012

Is enabling Double Escaping dangerous in ASP.NET?

Let's say we want to use plus sign in URL paths in our ASP.NET application.

For example: http://example.com/news/tag1+tag2/

If we try to request this URL, IIS(in fact, Request Filtering Module) will reject request with 404 error.

The only chance for me to do this was the following section in Web.config:
 <system.webServer>   
  <security>  
    <requestFiltering allowDoubleEscaping="true"/>  
  </security>  
 </system.webServer>  

With this setting everything works fine, except for the fact that we allow double escaping for all URLs in our application. So, is enabling double escaping dangerous?

Allowing double escaping points IIS to forward request to ASP.NET application, even if there is still encoded fragments in URL after first decoding.

Many would say that it's not big deal, but i decided not to risk, so i changed "+" delimiter in URL to "_" and removed section from Web.config.

So, my URLs look like:
http://example.com/news/tag1_tag2/

Wednesday, October 31, 2012

Constraint on Action names in MVC routing parameter

Let's say we have Web-site named "example.com" and controller with 3 Action methods:
 public class DiscussionController : BaseController  
 {  
      ...  
    public ActionResult One(string url)  
    {  
      var model= DiscussionService.GetDiscussionByUrl(url);  
      return View(model);  
    }  
    public ActionResult All()  
    {  
      ...  
    }  
    public ActionResult Popular()  
    {  
      ...  
    }  
 }  

We also have 2 registered routes(custom and standart MVC route):
 public static void RegisterRoutes(RouteCollection routes)  
 {  
   routes.MapRoute(  
     "Discussion",  
     "discussion/{url}",  
      new { controller = "Discussion" , action = "One" }  
    );  
   routes.MapRoute(  
     "Default",  
     "{controller}/{action}/{id}",  
     new { controller = "Home" , action = "Index" , id = "" }  
    );  
 }  

If we open "example.com/discussion/to-be-on-not-to-be/" URL in browser then One() Action method fires with url="to-be-on-not-to-be". So, our 1st route works fine.

But if we try to fire All() method with "example.com/discussion/all/" URL, we get One() method called again with url="all". Problem is that our 1st route fires before default route.

One solution is to use custom Constraint to filter names of controller's Action methods from our custom route:
 public static void RegisterRoutes(RouteCollection routes)  
 {  
    routes.MapRoute(  
      "Discussion",  
      "discussion/{url}",  
      new { controller = "Discussion" , action = "One" },   
      new { url = new ControllerMethodsConstraint<DiscussionController>("url" ) }  
     );   
     routes.MapRoute(  
       "Default",  
       "{controller}/{action}/{id}",  
       new { controller = "Home" , action = "Index" , id = "" }  
     );        
 }  

This Constraint class looks like:
 public class ControllerMethodsConstraint<T>: IRouteConstraint where T : BaseController  
 {  
    private readonly static IList<string> _occupiedMethodsNames;  
    private readonly string _idParamName;  
    static ControllerMethodsConstraint()  
    {  
      _occupiedMethodsNames = typeof(T).GetMethods().Where(m => m.IsPublic && (typeof (ActionResult ).IsAssignableFrom(m.ReturnType))).Select(m => m.Name.ToLower()).ToArray();  
    }  
    public ControllerMethodsConstraint(string idParamName)  
    {  
      _idParamName = idParamName;  
    }  
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)  
    {  
      return !_occupiedMethodsNames.Contains(((string )values[_idParamName]).ToLower());  
    }  
 }  

This Constraint actually just check if current param(in our case it is "url") value not equals to Action method names of specified controller.
If there is no Action methods with that name, then route is approved. Otherwise - not, so, next(default) route will work.

Tuesday, October 30, 2012

Lowercase route example in ASP.NET MVC

I like default URL routing behaviour of ASP.NET MVC, but sometimes you want something special.

Let's say we want Lower Case URLs in our Web site. Here's an example of Global.asax:
 public class MvcApplication : System.Web.HttpApplication  
   {  
     public static void RegisterGlobalFilters(GlobalFilterCollection filters)  
     {  
       filters.Add(new HandleErrorAttribute());  
     }  
     public static void RegisterRoutes(RouteCollection routes)  
     {  
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
       routes.MapLowercaseRoute(  
         "Default", // Route name  
         "{controller}/{action}/{id}", // URL with parameters  
         new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults  
       );  
     }  
     protected void Application_Start()  
     {  
       AreaRegistration.RegisterAllAreas();  
       RegisterGlobalFilters(GlobalFilters.Filters);  
       RegisterRoutes(RouteTable.Routes);  
     }  
   }  

MapLowercaseRoute is an extension method for RouteCollection class. It's looks like:
 public static class RoutesEx  
   {  
     public static void MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults)  
     {  
       routes.MapLowercaseRoute(name, url, defaults, null);  
     }  
     public static void MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults,  
                      object constraints)  
     {  
       if (routes == null)  
         throw new ArgumentNullException("routes");  
       if (url == null)  
         throw new ArgumentNullException("url");  
       var route = new LowercaseRoute(url, new MvcRouteHandler())  
       {  
         Defaults = new RouteValueDictionary(defaults),  
         Constraints = new RouteValueDictionary(constraints)  
       };  
       if (String.IsNullOrEmpty(name))  
         routes.Add(route);  
       else  
         routes.Add(name, route);  
     }      
   }  

The key point is LowercaseRoute class that does lowercasing:
 public class LowercaseRoute : Route  
   {  
     public LowercaseRoute(string url, IRouteHandler routeHandler)  
       : base(url, routeHandler) { }  
     public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)  
       : base(url, defaults, routeHandler) { }  
     public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)  
       : base(url, defaults, constraints, routeHandler) { }  
     public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler) : base(url, defaults, constraints, dataTokens, routeHandler) { }  
     public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)  
     {  
       var path = base.GetVirtualPath(requestContext, values);  
       if (path != null)  
         path.VirtualPath = path.VirtualPath.ToLowerInvariant();  
       return path;  
     }  
   }  

As you see, it's very easy to make some elaborations to default ASP.NET MVC routing machinery.

Monday, October 29, 2012

Defining methods in Razor syntax

Sometimes it's useful to use methods in Razor views. I mean not @helper methods that write out some markup, but methods that return any type you want.

Here's an example of controller, action, and corresponded Razor view template:
 public class HomeController: Controller  
 {  
   public ActionResult Index()  
   {  
    return View();  
   }  
 }  

Views/Home/Index.cshtml:
 <html>  
 <body>  
 @functions {  
  public int DoSomethingAndReturnResult(int someValue)  
  {  
   var result= someValue*2;  
   return result;  
   }  
 }  
 @{  
   var computedValue1 = DoSomethingAndReturnResult(2);  
   var computedValue2 = DoSomethingAndReturnResult(5);  
   <div >  
    @(computedValue1+computedValue2)  
   </div >  
  }  
 </body>  
 </html>  

As you see, we can use @functions syntax to define areas with methods, that we can use many times for some plain UI-purposes. I say "plain UI-purposes ", because we must remember that Views are bad place to put significant logic into.

Friday, October 26, 2012

Writing custom Windsor Controller Factory in ASP.NET MVC

Let's say we use Windsor IoC container in our ASP.NET MVC3 application. We registered some dependencies in Global.asax bootstrapper and now we need somehow to resolve them in our controller.

Of course we can do this:
 public class MyController : BaseController  
 {   
   private IFoo _dependency;   
   public MyController()  
   {  
    _dependency = Container.Resolve<IFoo>();   
   }  
   public ActionResult Index()  
   {   
    _dependency.DoSomething(); 
     ... 
   }  
 }  

But it is not good solution, because now we have dependency on IoC container itself in our controller. Besides, using any forms of Service Locator is a bad design practice.

More elegant solution is to write custom Controller Factory(in our case it is Windsor Controller Factory):
 public class WindsorControllerFactory : DefaultControllerFactory  
 {  
   private readonly IKernel _kernel;  
   public WindsorControllerFactory(IKernel kernel)  
   {  
    _kernel = kernel;  
   }  
   public override void ReleaseController(IController controller)  
   {  
    _kernel.ReleaseComponent(controller);  
   }  
   protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)  
   {  
    if (controllerType == null)  
    {  
      throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));  
    }  
    var controller = (Controller)_kernel.Resolve(controllerType);      
    return controller;  
   }  
 }  

And then to register this factory as default Controller Factory in our MVC application in Global.asax:
 Container = new WindsorContainer();  
 ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container.Kernel));  

Now we can do elegant dependency injections in our controller's constructor without references on specific IoC(in our case it's Castle Windsor):
 public class MyController : BaseController  
 {  
   private IFoo _dependency;  
   public MyController(IFoo dependency)  
   {  
    _dependency = dependency;  
   }  
   public ActionResult Index()  
   {  
    _dependency.DoSomething();
     ...
   }  
 }  

Monday, October 22, 2012

Cookie value is nulled when using Response.Cookies

I have the following code to check if Cookie with name "city" already exists in Response.Cookies collection:
 if (HttpContext.Current.Response.Cookies["city"]!=null)   
   return HttpUtility.UrlDecode(HttpContext.Current.Response.Cookies["city"].Value);  

But to my big surprise this code is not working in that way that i expected. This code resets Cookie value to NULL when i am trying to check if Cookie value is not NULL.

Here the code that works fine for me:
 if (HttpContext.Current.Response.Cookies.AllKeys.Contains("city"))  
   return HttpUtility.UrlDecode(HttpContext.Current.Response.Cookies["city"].Value);  


Thursday, October 18, 2012

Dependency injection in ASP.NET MVC 3 validation attributes

In previous article(Dependency injection in ASP.NET MVC 3 action filters) we have seen how to inject dependencies in MVC Action Filters. Now let's try to inject dependency in Validation attribute. Validation attributes is used in MVC Model Validation. There are many useful built-in attributes, but often you need to write your own.

Let's imagine that we need attribute that validate that user's login(typed in registration form) is not occupied. So we write custom attribute:
 public class LoginExistanceValidatorAttribute : ValidationAttribute  
 {  
   public IRegistrator Registrator { get ; set ; }  
   public override bool IsValid(object value)  
   {  
      var valueStr = value as string;  
      if (string.IsNullOrEmpty(valueStr))  
       return false;  
      return Registrator.CheckLoginExistance(valueStr);  
    }  
 }  

Our attribute needs IRegistrator dependency to be injected. So, how to inject it? We have problem like one than we have discussed in previous article with Action Filters. And we have similar solution(as before, we use Castle Windsor IoC container):
 var container = new WindsorContainer();   
 container.Register(Component.For<ModelValidator>().ImplementedBy<WindsorModelValidator>().LifeStyle.Transient);   
 DataAnnotationsModelValidatorProvider.RegisterDefaultAdapterFactory((metadata, context, attribute) => container.Resolve<ModelValidator>(new { metadata, context, attribute }));  

All we need is to write custom Model Validator WindsorModelValidator that will inject dependencies in Validation attribute at some point. Example:
 public class WindsorModelValidator : DataAnnotationsModelValidator  
 {  
   public IWindsorContainer Container { get ; set ; }  
   public WindsorModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute): base(metadata, context, attribute)
   {  
   }  
   public override IEnumerable<ModelValidationResult> Validate(object container)  
   {  
     // inject the services from the container that  
     // the Validation attribute requires  
     Container.Kernel.InjectProperties(Attribute);  
     ValidationContext context = CreateValidationContext(container);  
     ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context);  
     if (result != ValidationResult.Success)  
     {  
       yield return new ModelValidationResult  
       {  
         Message = result.ErrorMessage  
       };  
     }  
   }  
   protected virtual ValidationContext CreateValidationContext(object container)  
   {  
     var context = new ValidationContext(container ?? Metadata.Model, new WindsorServiceProvider(Container), null );  
     context.DisplayName = Metadata.GetDisplayName();  
     return context;  
    }  
 }  

All magic is in this line:
 Container.Kernel.InjectProperties(Attribute);  

We again use this extension method to inject dependencies in object. You can view code of this method in previous article about Action filters.

Wednesday, October 17, 2012

Dependency injection in ASP.NET MVC 3 action filters

So far it's not easy task to inject dependencies in MVC 3 action filters.

For example, we have action filter attribute that performs redirection to Login page if user is not authorized:
 public class AuthorizeAttribute : ActionFilterAttribute  
 {  
   public ISiteUser SiteUser { get; set; }   
   public override void OnActionExecuting( ActionExecutingContext filterContext)  
   {  
     if (!SiteUser.IsAuthenticated)  
     {  
       var urlHelper = new UrlHelper(HttpContext .Current.Request.RequestContext);  
       if (urlHelper.RequestContext.HttpContext.Request.Url != null)  
       {  
        filterContext.Result = new RedirectResult(urlHelper.Action("Login" , "Authentication" , new { ReturnUrl = urlHelper.RequestContext.HttpContext.Request.Url.PathAndQuery }));   
       }   
     }  
   }   
 }  

This action filter has dependency ISiteUser. So, how to inject concrete implementation of SiteUser there? It is good design practice to inject dependencies in constructor. But at this point we do not control moment when this attribute is created and we do not have any way
to catch this moment.

What we can to do is to write custom ActionInvoker(using Castle Windsor IoC container, for example) and to step in process of controller action invocation:
 public class WindsorActionInvoker : ControllerActionInvoker  
 {  
   private readonly IKernel _kernel;  
   public WindsorActionInvoker(IKernel kernel)  
   {  
     _kernel = kernel;  
   }  
   protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter > filters, ActionDescriptor actionDescriptor, IDictionary<string , object > parameters)  
   {  
     foreach (IActionFilter actionFilter in filters)  
     {  
      _kernel.InjectProperties(actionFilter);  
     }  
     return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);  
   }  
 }  

As you can see, we iterate through controller action filters and call InjectProperties extension method which magically performs dependency injections.

Let's look at this method:
 public static class WindsorExtensions  
 {  
   public static void InjectProperties(this IKernel kernel, object target)  
   {  
     var type = target.GetType();  
     foreach (var property in type.GetProperties( BindingFlags.Public | BindingFlags.Instance))  
     {  
      if (property.CanWrite && kernel.HasComponent(property.PropertyType))  
      {  
        var value = kernel.Resolve(property.PropertyType);  
        try  
        {  
          property.SetValue(target, value, null);  
        }  
        catch ( Exception ex)  
        {  
          var message = string.Format("Can't set property {0} on type {1}", property.Name, type.FullName);  
          throw new InvalidOperationException(message, ex);  
        }  
      }  
     }  
   }  
 }  

Now all the magic has gone without a trace. We simply iterate through properties of Action Filter and try to resolve them using Castle Windsor kernel. Of course this dependencies should be registered before. Also we need to setup WindsorActionInvoker as default ActionInvoker in our Web Application:
 var container = new WindsorContainer();  
 DependencyResolver.SetResolver(new WindsorDependencyResolver(container.Kernel));  
 container.Register(Component.For<ISiteUser>().ImplementedBy<SiteUser>());  
 container.Register(Component.For<IActionInvoker>().ImplementedBy<WindsorActionInvoker>().DependsOn(Property.ForKey( "kernel").Eq(container.Kernel)).LifeStyle.Transient);  

One more important point here is to setup custom WindsorDependencyResolver. This class will be used to resolve dependencies instead of default MVC dependency resolver(which actually just uses Activator.CreateInstance method). Our resolver looks like this:
 public class WindsorDependencyResolver : System.Web.Mvc.IDependencyResolver  
 {  
   private readonly IKernel _kernel;  
   public WindsorDependencyResolver(IKernel kernel)  
   {  
     _kernel = kernel;  
   }  
   public object GetService(Type serviceType)  
   {  
    return _kernel.HasComponent(serviceType) ? _kernel.Resolve(serviceType) : null ;  
   }  
   public IEnumerable<object > GetServices(Type serviceType)  
   {  
     return _kernel.HasComponent(serviceType) ? _kernel.ResolveAll(serviceType).Cast<object >() : new object [] { };  
   }  
 }  

Tuesday, October 16, 2012

Testing ASP.NET MVC routes using NUnit and FakeItEasy

Let's say we have registered routes in our ASP.NET MVC application:
 routes.MapTrailingSlashRoute(  
   "Topic", // Route name  
   "news/{url}", // URL with parameters  
    new { controller = "Topic", action = "Index" } // Parameter defaults  
 );  
 
 routes.MapTrailingSlashRoute(  
   "Default", // Route name  
   "{controller}/{action}/{id}", // URL with parameters  
   new { controller = "Home", action = "Index" , id = "" } // Parameter defaults  
 );  

How can we test this routes using NUnit testing framework and FakeItEasy mocking framework?

Here's an example of how this can be done:
     [TestFixture]  
     [Category("Unit")]  
     public class when_using_registered_routes  
     {                    
       [TestFixtureSetUp]  
       public void Prepare()  
       {  
         MvcApplication.RegisterRoutes(RouteTable .Routes);   
       }  
       [Test]  
       [TestCase("~/", "Home", "Index" )]        
       [TestCase( "~/news/testing-routes-in-mvc/", "Topic" , "Index" )]  
       [TestCase("~/discussion/all/", "Discussion", "All")]        
       [TestCase( "~/discussion/widget/", "Discussion" , "Widget" )]  
       public void should_return_expected_controller_and_action(string path, string expectedController, string expectedAction)  
       {                  
         var httpContext = A.Fake<HttpContextBase>();          
         A.CallTo(() => httpContext.Request.AppRelativeCurrentExecutionFilePath).Returns(path);                  
         var routeData = RouteTable.Routes.GetRouteData(httpContext);  
         Assert.That(routeData.Values["controller"].ToString().ToLower(), Is.EqualTo(expectedController.ToLower()));  
         Assert.That(routeData.Values["action"].ToString().ToLower(), Is.EqualTo(expectedAction.ToLower()));  
       }       
     }  

Monday, October 15, 2012

How to remove component in Castle Windsor 3.0?

Say we have registered component in Castle Windsor:
 Container.Register(Component.For<IRegistrator>().ImplementedBy<TestRegistratorWhichReturnsGoodResult>());  

Sometimes in Unit tests i need to remove registered component from Castle Windsor and to register new one. Prior to 3.0 version we can do this:
 Container.Kernel.RemoveComponent(typeof(TestRegistratorWhichReturnsGoodResult).FullName);  
 Container.Register(Component.For<IRegistrator>().ImplementedBy<TestRegistratorWhichReturnsBadResult>());  

Аfter version 3.0 breaking changes we can't do this, because there is no RemoveComponent method in version 3.0.
But we can use the following approach:
  class RegistrationHandlerSelector :IHandlerSelector  
       {  
         public static bool UseBadResultRegistrator { private get; set; }  
         public bool HasOpinionAbout(string key, Type service)  
         {  
           return service == typeof(IRegistrator);            
         }  
         public IHandler SelectHandler(string key, Type service, IHandler[] handlers)  
         {  
           return handlers.First(x => UseBadResultRegistrator ? x.ComponentModel.Implementation == typeof (TestRegistratorWhichReturnsBadResult ) :  
                                      x.ComponentModel.Implementation == typeof (TestRegistratorWhichReturnsGoodResult ));                      
         }  
       }  

 Container.Register(Component.For<IRegistrator>().ImplementedBy<TestRegistratorWhichReturnsGoodResult>());  
 Container.Register(Component.For<IRegistrator>().ImplementedBy<TestRegistratorWhichReturnsBadResult>());  
 Container.Kernel.AddHandlerSelector(new RegistrationHandlerSelector());  

Now we can use RegistrationHandlerSelector.UseBadResultRegistrator field to choose which component to use.

MVC: organize your models properly

ASP.NET MVC is an excellent framework for developing scalable, testable and flexible Web applications. But bad approach can lead to bloated Controllers, poorly organized Views and chaos in Models. This article focuses on the approach for organization of models that is used successfully in several large web projects.
Consider, for example, a page which contains a large amount of information generated on server. This information may come from various sources. Following MVC paradigm we have to prepare a model that contains all necessary information and bind it to the appropriate view for display.

Consider HomeController:
 public class HomeController : BaseController  
   {  
     private readonly HomeIndexViewDataBuilder _homeIndexViewDataBuilder;  
     private readonly HomeInfoViewDataBuilder _homeInfoViewDataBuilder;  
     public HomeController(Context context, HomeIndexViewDataBuilder homeIndexViewDataBuilder, HomeInfoViewDataBuilder homeInfoViewDataBuilder)  
       : base(context)  
     {  
       _homeIndexViewDataBuilder = homeIndexViewDataBuilder;  
       _homeInfoViewDataBuilder = homeInfoViewDataBuilder;  
     }     
     public ActionResult Index()  
     {        
       var model = _homeIndexViewDataBuilder.Build();        
       return View(model);      
     }  
     public ActionResult Info(string id)  
     {  
       var model = _homeInfoViewDataBuilder.Build(id);  
       if (model!= null)  
        return View(model);  
       return TransferToNotFound();  
     }            
   }  

In order not to bloat controllers, preparation of model with necessary information takes place in Builder. In our convention Builder is a class that corresponds 1:1 to Controller-Action method and contains a single method Build. We use the following naming convention: if controller is named HomeController and Action-method is named Index then correspond Builder, will be called HomeIndexViewDataBuilder. It may look like this:
 public class HomeIndexViewDataBuilder : BaseModelBuilder  
   {  
    private readonly TopicQuery _topicQuery;  
     public HomeIndexViewDataBuilder(IModelCacher modelCacher, TopicQuery topicQuery): base(modelCacher)  
     {  
       _topicQuery = topicQuery;  
     }  
     public HomeIndexViewData Build()  
     {  
       var homeIndexViewData = new HomeIndexViewData()  
       /*filling model(fetching data from database, cache or other builders)*/  
       return homeIndexViewData;  
     }  
   }  

You can injects any objects in your Builder. In this example, objects of the following classes are injected: ModelCacher is a class for caching models, TopicQuery is a class used to fetch news from database. In some cases parameters to Build method can be passed (eg, news ID or something else). Build method returns a model that contains all necessary information to be displayed on the home page. This model does not contain any logic, only flat data for display. It may look like this:
 public class HomeIndexViewData  
   {  
     public IDictionary<string , NewsTeaserViewModel []> Teasers { get; set; }      
     public NewsTeaserViewModel[] Top { get ; set ; }      
     public NewsTeaserViewModel[] EditorsChoice { get ; set ; }      
     public NewsTeaserViewModel[] MostViewed { get ; set ; }      
     public NewsTeaserViewModel[] MostCommented { get ; set ; }      
     public NewsGalleryTeaserViewModel[] LastGalleries { get ; set ; }  
   }  

Class name follows our naming convention. That is, if Builder is called HomeIndexViewDataBuilder, then model will be HomeIndexViewData. When we say ViewData we mean a composite model. This composite model consists of variety of models, such as: NewsTeaserViewModel and NewsGalleryTeasersViewModel. By ViewModel we mean a simple model. For example, NewsTeaserViewModel may look like:
 public class NewsTeaserViewModel  
   {  
     public Guid Id { get; set; }  
     public string Url { get; set; }  
     public string Title { get; set; }  
     public string Description { get; set; }  
     public Guid? Image { get; set; }  
     public string Rubric { get; set; }  
     public DateTime? PublicationDate { get; set; }  
     public uint Comments { get; set; }  
  }  

Differences between ViewData and ViewModel:


ViewData - is a composite model returned by Builder. Builder corresponds 1:1 to a Controller-Action method. For example: HomeIndexViewDataBuilder returns HomeIndexViewData, HomeInfoViewDataBuilder returns HomeInfoViewData etc. These models are used only in correspond Controller-Action methods and nowhere else.

ViewModel - is a simple model, which is a part of any composite ViewData models. One ViewModel can be included in various ViewData models. For example, NewsTeaserViewModel can be used on the home page(in HomeIndexViewData) or on the game page(in GameIndexViewDataBuilder) or somewhere else.

Friday, October 12, 2012

Transferring to error pages from Application_Error handler in MVC3

Our task is to implement transferring(not redirection) to correspond error page when error occurs in ASP.NET MVC3 application.

Good solution for redirection to error pages is to use <customErrors> section in web.config. But we need transferring for SEO purposes.

So it was obvious to use httpErrors section instead of customErrors section:
  <httpErrors errorMode="Custom" existingResponse =" Replace" >  
     < clear />  
     < error statusCode =" 403" path= "/Error/Forbidden " responseMode="ExecuteURL" />  
     < error statusCode =" 404" path= "/Error/NotFound " responseMode="ExecuteURL" />  
     < error statusCode =" 500" path= "/Error/InternalError " responseMode="ExecuteURL" />  
   </ httpErrors>  

It's good solution, but it works only when your application is under website root. If your application is under virtual directory transferring will be broken.

The only solution i found is to use Application_Error handler in Global.asax instead of config:
 protected void Application_Error(object sender, EventArgs e)  
     {        
       var exception = Server.GetLastError();  
       if (Context.Request.IsLocal)  
         return;  
       var actionName = "InternalError";  
       if (exception is HttpException)  
       {  
         var code = (exception as HttpException).GetHttpCode();  
         switch (code)  
         {  
           case 400:  
             actionName = "NotFound";  
             break;  
           case 403:  
             actionName = "Forbidden";  
             break;  
           case 404:  
             actionName = "NotFound";  
             break;  
         }  
       }        
       var path = string.Format( "~/Error/{0}/" , actionName);        
       Server.TransferRequest(path, false);        
     }  

Code is obvious and it works fine almost for all cases. ALMOST, but not for all.

I am sure you know popular ASP.NET exception "A potentially dangerous Request.Form value was detected from the client". This exception happens when you(or ASP.NET) try to extract QueryString values, but there is "potential dangerous" in values: html tags, for example.

So, exception happens, then our Application_Error handler fires. Then we use Server.TransferRequest which PRESERVE QueryString of current request despite on second "false" parameter. Now we have "potential dangerous" again in our QueryString during this transferring, which wll trigger Application_Error again, and so on.  What we get here is cyclical transferring that can kill Application Pool easily.

To force Server.TransferRequest NOT to save QueryString of current request you have to specify QueryString explicitly in your transferring URL. For example:
 var path = string.Format( "~/Error/{0}/?transfer=1" , actionName);