Thursday, December 1, 2011

Programmatic way to add filters for NHibernate mappings

NHibernate filters is a powerful mechanism for selective filtering of records. Read more here or here.

This post is to document the way to add filters programmatically rather than declaratively (in binding files).

Let’s start with a declarative configuration.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
    namespace="yournamespace" assembly="yourassembly">
    <class name="Parent" table="[dbo].[Parents]" >
        <id name="Oid" column="[OID]" type="Int32" >
            <generator class="native" />
        </id>
        <property name="Name" column="Name" type="String" not-null="false" length="50" /> 
        <bag name="Children" inverse="true" cascade="all-delete-orphan" lazy="true" >
            <key>
                <column name="[ID_PARENT]" />
            </key>
            <one-to-many class="Child" />
            <filter name="association-level-filter" condition="condition" />
        </bag>
        <filter name="entity-level-filter" condition="condition" />
    </class>
</hibernate-mapping>
 

Note that the mapping defined the entity of type Parent with a reference to a list of entities of type Child. Each Child points to its Parent.

Note also that there are actually two filters – the entity-level filter applies to queries to type Parent and the association-level filter applies to queries involving the list of dependant entities.

The entity-level filter is available on the mapping object easily:

foreach ( var mapping in config.ClassMappings )
{
    mapping.AddFilter( "name", "criteria" );
}

However, to get the association-level filter you have to dig deeper to get the properties of type Bag from the actual mapping:

foreach ( var mapping in config.ClassMappings )
{
    mapping.AddFilter( "name", "condition" );
    foreach ( var property in mapping.PropertyIterator )
        if ( property.Value is Bag )
        {
            Bag bagProperty = (Bag)property.Value;
 
            bagProperty.AddFilter( "name", "condition" );
        }
}

Thursday, November 17, 2011

MSIS7042: The same client browser session has made 'X' requests in the last 'Y' seconds.

This exception has been written to the ADFS event log after unsusccessful sign-in of one of our Relying Party applications. From the user perspective, the control flow seems correct, the application redirects to the ADFS login page but then rather than signing in, it forces the browser to go to ADFS again and again. After few frantic redirects within the browser, ADFS shows the exception message.

It turned out that there is a simple cause of such unindented behaviour – the FederatedPassiveSignIn control on the RP’s login page has the AutoSignIn property set to true.

When the browser hits the page, it unconditionally redirects to ADFS and then, upon returning when something is wrong, it redirects to ADFS again. Problem is that the ADFS shows the login page only once and then it automatically redirects back to the application because user is already authenticated. This causes the “redirection loop” within the browser as the application and ADFS start to unconditionally redirect between each other.

If this is the case in your scenario (AutoSignIn==”true”), then there’s a simple workaround. All you have to do is to provide a SignInError handler for the control where you had to turn off the auto signing:

FederatedPassiveSignIn1.SignInError +=
    ( s, e ) =>
    {
        // turn off auto signing to prevent the "redirection loop"
        FederatedPassiveSignIn1.AutoSignIn = false;
        // optionally show the error message 
        lblError.Text = e.Exception.Message;
    };

In our case it turned out that the reason for the error in the authentication pipeline was caused by wrong STS certificate thumbprint at the RP-side which caused WIF to throw a security exception from the IssuerNameRegistry.

Tuesday, November 15, 2011

Easy Unity Application Block integration in .NET applications

Unity Application Block is a lightweight dependency injection container from Microsoft Patterns & Practices. This article is intended to show how quickly and easily integrate Unity with your code.

Start by downloading and installing Unity. The current version, 2.1, consist of 5 libraries:

  • Microsoft.Practices.ServiceLocation.dll
  • Microsoft.Pracitces.Unity.dll
  • Microsoft.Practices.Unity.Configuration.dll
  • Microsoft.Practices.Unity.Interception.dll
  • Microsoft.Practices.Unity.Interception.Configuration.dll

There are at least two ways to define type bindings in Unity – declaratively in a *.xml file and programmatically in a C# code.

The nice thing is that you can combine both approaches in desired order so for example you first create few mappings programmatically and then load the static configuration which can possibly override some of mappings.

Now create a new application (Windows or web) and add references to unity libraries (first 3 will do as this tutorial doesn’t cover interceptions).

Anyway, first go to the application *.config file (app.config for Windows applications, web.config for web apps) and inform the runtime that you are going to configure unity using the *.xml file:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="unity" 
         type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
               Microsoft.Practices.Unity.Configuration"/>
    </configSections>
    <unity configSource="Configuration\unity.config"/>
</configuration>

As you can see I am delegating the Unity configuration to a separate file, Configuration\unity.config. This is a good practice as you have all the IoC configuration in a single place which doesn’t interfere with any other application settings.

For this tutorial, create a service specification and two implementations:

public interface ICustomService
{
    string BusinessOperation();
}
 
public class CustomServiceImpl : ICustomService
{
    #region ICustomService Members
 
    public string BusinessOperation()
    {
        return "foo";
    }
 
    #endregion
}
 
public class CustomServiceImpl2 : ICustomService
{
    #region ICustomService Members
 
    public string BusinessOperation()
    {
        return "bar";
    }
 
    #endregion
}

We are going to provide a static mapping in the *.xml file, Configuraton\unity.config:

<?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <container>
        <register type="ConsoleApplication30.Logic.ICustomService, ConsoleApplication30"
                  mapTo="ConsoleApplication30.Logic.CustomServiceImpl, ConsoleApplication30" />
    </container>
</unity>

As you can see, the interface ICustomService is mapped to CustomServiceImpl.

The remaining part is to configure the service locator:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Microsoft.Practices.ServiceLocation;
using ConsoleApplication30.Logic;
 
namespace ConsoleApplication30
{
    class Program
    {
        static void Main( string[] args )
        {
            UnityServiceLocator locator = new UnityServiceLocator( CreateConfiguredUnityContainer() );
            ServiceLocator.SetLocatorProvider( () => locator );
 
 
        }
 
        private static IUnityContainer CreateConfiguredUnityContainer()
        {
            IUnityContainer container = new UnityContainer();
 
            // (optional) provide default mappings programmatically
            container.RegisterType<ICustomService, CustomServiceImpl2>();
 
            // (optional) load static config from the *.xml file
            container.LoadConfiguration();
 
            return container;
        }
    }
}

As you can see the locator is created over a container which shows how to perform dynamic and static configuration.

Remember that Unity, as most of IoC containers, allows to reregister services – if you provide two or more mappings of the same service type to a concrete implementation, the last registered implementation is always used when you resolve the service (which is reasonable). In this tutorial I am creating a mapping in code from ICustomService to CustomServiceImpl2.

From now on you can ask the service locator services and consume them:

ICustomService service = ServiceLocator.Current.GetInstance<ICustomService>();
var foo = service.BusinessOperation();

It couldn’t be easier. Personally, when I am free to pick an IoC container, I often pick Unity – it’s reliable, simple and lightweight.

A quick quiz: in the example, I am mapping the implementation to CustomServiceImpl2 and in the next line I am loading the configuration from the *.xml file which in turn maps the implementation to CustomServiceImpl then what would be the result of resolving the service type?

Friday, November 4, 2011

Managing cookies in a WCF client

This article shows a way to manage cookies in an instance of a client proxy to a WCF service.

Background

Years ago, when we all were using the SoapHttpClientProtocol proxies, there was a property called CookieContainer. What we had to do was to create a new cookie container for the client instance and push/pull cookies from there.

Nowadays we use client proxies which derive from System.ServiceModel.ClientBase. Unfortunately, there’s no cookie container on such proxy – this is reasonable as the proxy could be used to contact a WCF Service over TCP or MSMQ where the term “http cookie” is meaningless.

Existing solutions

There are two well-known approaches to the problem, both clearly described in a blog entry by Enrico Campidoglio. First, you could take control over http headers using clumsy:

MyWebServiceClient client = new MyWebServiceClient();
 
using ( new OperationContextScope( client.InnerChannel ) )
{
    HttpRequestMessageProperty request = new HttpRequestMessageProperty();
    request.Headers["Cookie"] = "cookie header value";
 
    OperationContext.Current.OutgoingMessageProperties[
        HttpRequestMessageProperty.Name] = request;
 
    client.InvokeSomeMethod();
}

This way you can alter the way cookies are handled for a single request.

A more general approach involves writing a custom message inspector. Consult Enrico’s article for more details.

Another approach

Is it really such difficult? Is the WCF Client proxy so dumb that it cannot handle cookies on its own?

Well, it can. It seems that setting the AllowCookies property on a BasicHttpBinding to true turns on the automatic cookie management. From this moment, you can’t use any of the previously mentioned solutions because it is the client proxy to retrieve cookies and automatically append them to consecutive requests.

Wait! But you can’t append a new cookie on the client-side this way! And this was our primary requirement.

Well, you can. If you ask the server to do so.

[ServiceContract]
[ServiceBehavior(
    InstanceContextMode = InstanceContextMode.PerCall,
    ConcurrencyMode = ConcurrencyMode.Multiple,
    UseSynchronizationContext = false )]
[AspNetCompatibilityRequirements( 
   RequirementsMode = AspNetCompatibilityRequirementsMode.Required )]
 
public class TheService 
{
    // Append the cookie to the client
    [OperationContract]
    public void SetCookie( string Name, string Value )
    {
        HttpCookie cookie = new HttpCookie( Name, Value );
 
        HttpContext.Current.Response.AppendCookie( cookie );
    }
 
    // other service methods follow
}

And the client:

BasicHttpBinding binding = new BasicHttpBinding();
binding.AllowCookies = true;
 
EndpointAddress address = 
   new EndpointAddress( "http://localhost:12345/TheService.svc" );
 
TheServiceReference.TheServiceClient client = 
   new TheServiceReference.TheServiceClient( binding, address );
 
// ask the server to append the cookie
client.SetCookie( "foo", "bar" ); 

And that’s it. At the cost of one extra server request, the WCF client is able to take a full control over it’s cookies. Please add any additional methods as needed (for example to remove cookies).

Wednesday, October 19, 2011

Reading the revision number of a local copy of a SVN repository

The SVN client (TortoiseSVN) has a handy SubWcRev.exe application which is commonly used for obtaining the revision number of a local copy of given SVN repository and (optionally) rewriting text files and replace the $WCREV$ token with the retrieved version number.

This post is to document the way we mimic SubWcRev.exe for our internal purposes.

TortoiseSVN 1.6 and earlier

When TortoiseSVN 1.6 (or earlier) is used, each folder in the repository tree contains a .svn subfolder. In there, the file named entries contains some information about the local repository. The root svn subfolder can be used as the source of the revision number - the entries file located there always contains the revision number in the third line:

public class SvnManager
{
    public string FolderName { get; private set; }
 
    public SvnManager( string FolderName )
    {
        this.FolderName = FolderName;
    }
 
    const string ENTRIES = "entries";
    private string RevisionNumber
    {
        get
        {
            string SvnSubfolder = FolderName + "\\.svn";
 
            if ( Directory.Exists( SvnSubfolder ) )
            {
                string EntriesFile = Directory.GetFiles( SvnSubfolder, ENTRIES ).FirstOrDefault();
 
                if ( !string.IsNullOrEmpty( EntriesFile ) )
                {
                    string[] Lines = File.ReadAllLines( EntriesFile );
                    if ( Lines.Length > 3 )
                        return Lines[3];
                }
            }
 
            return string.Empty;
        }
    }
}

The client code would be:

SvnManager manager = new SvnManager( "local repository root path" );
string revisionNumber = manager.RevisionNumber;

Tortoise 1.7

Tortoise 1.7 no longer creates .svn subfolders in each single folder of the local copy of your repository. Instead, a SQLite database, wc.db, is created in the .svn folder at the root level of the local copy. The database is a binary file, however it seems that the revision number is stored as string value which makes it possible to match the binary data for a regular expression, /!svn/ver/[0-9]*/:

public class SvnManager
 {
     public string FolderName { get; private set; }
 
     public SvnManager( string FolderName )
     {
         this.FolderName = FolderName;
     }
     
     const string DB      = "wc.db";
     const string PATTERN = "/!svn/ver/(?'version'[0-9]*)/";
     private string RevisionNumber
     {
         get
         {
             string SvnSubfolder = FolderName + "\\.svn";
 
             if ( Directory.Exists( SvnSubfolder ) )
             {
                 int maxVer = int.MinValue;
                 string EntriesFile = Directory.GetFiles( SvnSubfolder, DB ).FirstOrDefault();
 
                 if ( !string.IsNullOrEmpty( EntriesFile ) )
                 {
                     byte[] fileData = File.ReadAllBytes( EntriesFile );
                     string fileDataString = Encoding.Default.GetString( fileData );
 
                     Regex regex = new Regex( PATTERN );
 
                     foreach ( Match match in regex.Matches( fileDataString ) )
                     {
                         string version = match.Groups["version"].Value;
 
                         int curVer;
                         if ( int.TryParse( version, out curVer ) )
                             if ( curVer > maxVer )
                                 maxVer = curVer;
                     }
 
                     if ( maxVer > int.MinValue )
                         return maxVer.ToString();
                 }
             }
 
             return string.Empty;
         }
     }     
 }