Tag Archives: C#

Asp.Net MVC Code

Unit of Work, NHibnernate and Asp.Net MVC

In a previous post I mentioned for some projects I’m using a combination of NHibernate, unit of work and asp.net mvc; this post will give an example of how I set this up for a project and how to get mvc to automatically create instances of UoW, wrap our code in transactions and clean up after it’s self via ActionFilterAttributes. Some of the code I have is a modified version of this but probably not as nice.

Here is a list of the interfaces that’ll be created:

And classes that implement them:

And finally the mvc Attribute: UnitOfWorkFilter.

This maybe(is) a lot of work for for something that seems pretty straight forward but it allows the code to be decoupled and makes testing much easier.  For example a project I’ve been working on uses this workflow and has a windows service to do some back end processing; by creating a RequestState to work with a windows service the rest of the code doesn’t need changing (apart from the filter obviously.)

I’ll leave the code further down in the post so things don’t get messy.

Actually using this setup.

This post makes the assumption that your data access is all via nhibernate and you’re using the repository pattern or something similar. Your repositories will need access to the IActiveSessionManager. If you’re using a DI like Ninject it should pass it through for you.

In your repository you can access the nhibernate session like so:

this.activeSessionManager.GetActiveSession();

I personally have a property to do this for me:

    public ISession Session
    {
      get
      {
        return this.activeSessionManager.GetActiveSession();
      }
    }

From here on do what ever queries you need, all the repositories in the will share the same session during the same request.

Applying the attribute

You can either have the UnitOfWorkFilter attached to each controller/method or in the global.asax you can register is as a global filter.

 [UnitOfWorkFilter]
  public class UserController : Controller
{
}

or

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new UnitOfWorkFilter());

    }

That’s it!.

How it all fits together

Imagine you have a controller that gets you a list of users (UserController).

  1. You issue a GET to the controller action
  2. The UnitOfWorkFilter kicks in and starts a new transaction from the ActiveSessionManager (The same manager your repo’s use)
  3. The ActiveSessionManager checks for/creates a new nhibernate session to work with
  4. Your repos use this ActiveSessionManager/NHibernate session to get its data
    1. If you have more than one repo in the controller action then no new sessions are created, the same one is shared.
  5. The controller returns the users
  6. The UnitOfWorkFilter then commits the transaction and closes the current session
    1. If something goes wrong like an exception the the UnitOfWorkFilter rollsback the transaction – preserving the integrity of the database

Below is the code to implement this.

IUnitOfWork

  public interface IUnitOfWork : IDisposable
  {

    void BeginTransaction();

    void EndTransaction();

    void RollBack();
  }

IRequestState

  public interface IRequestState
  {
    T Get<T>(string key);

    void Store(string key, object something);
  }

ISessionProvider

The ISession is the NHibernate session.

  public interface ISessionProvider
  {
    ISession Create();
  }

IActiveSessionManager

  public interface IActiveSessionManager: IDisposable
  {
    ISession GetActiveSession();

    void ClearActiveSession();

    bool HasActiveSession { get; }
  }

UnitOfWork

/// <summary>
  /// An nhibernate specific implementation of the unit of work concept
  /// </summary>
  public class UnitOfWork : IUnitOfWork
  {
    private readonly IActiveSessionManager sessionManager;

    private ITransaction transactionScope;

    public UnitOfWork(IActiveSessionManager sessionManager)
    {
      this.sessionManager = sessionManager;
    }

    public void Dispose()
    {
      if (this.transactionScope != null)
      {
        this.transactionScope.Dispose();
      }

      this.sessionManager.Dispose();
    }

    public void BeginTransaction()
    {
      if (this.transactionScope != null)
      {
        throw new InvalidOperationException("Transaction already started; nested transactions are not supported");
      }

      this.transactionScope = this.sessionManager.GetActiveSession().BeginTransaction();
    }

    public void EndTransaction()
    {
      if (this.transactionScope == null)
      {
        throw new InvalidOperationException("No active transaction found");
      }

      if (!this.transactionScope.IsActive)
      {
        throw new InvalidOperationException("This transaction is no longer active");
      }

      try
      {
        this.transactionScope.Commit();
      }
      catch (Exception ex1)
      {
          this.RollBack();
      }
    }

    public void RollBack()
    {
      this.transactionScope.Rollback();
    }
  }

AspNetRequestState

  public class AspNetRequestState : IRequestState
  {
    public T Get<T>(string key)
    {
      return (T)HttpContext.Current.Items[key];
    }

    public void Store(string key, object something)
    {
      HttpContext.Current.Items[key] = something;
    }
  }

SessionProvider

Note that the session factory has not been configured, this is left up you to configure.

 public class SessionProvider : ISessionProvider
  {
    private static ISessionFactory sessionFactory;

    public SessionProvider()
    {
      if (sessionFactory == null)
      {
	    // Do your mhibernate configuration here
        var configration = new Configuration();
        sessionFactory = configration.BuildSessionFactory();
      }
    }

    public ISession Create()
    {
      return sessionFactory.OpenSession();
    }
  }

ActiveSessionManager

public class ActiveSessionManager : IActiveSessionManager
  {
    private const string sessionKey = "_currentSession";

    private readonly IRequestState requestState;

    private readonly ISessionProvider sessionProvider;

    public ActiveSessionManager(IRequestState requestState, ISessionProvider sessionProvider)
    {
      this.requestState = requestState;
      this.sessionProvider = sessionProvider;
    }

    public ISession GetActiveSession()
    {
      if (this.Current == null)
      {
        var newSession= this.sessionProvider.Create();
        this.Current = newSession;
        return newSession;
      }

      return this.Current;
    }

    public void ClearActiveSession()
    {
      this.Current = null;
    }

    public bool HasActiveSession
    {
      get { return this.Current != null; }
    }

    protected virtual ISession Current
    {
      get
      {
        return requestState.Get<ISession>(sessionKey);
      }
      set
      {
        requestState.Store(sessionKey, value);
      }
    }

    public void Dispose()
    {
      var session = this.Current;
      if(session != null)
      {
        session.Dispose();
        this.ClearActiveSession();
      }
    }
  }

 

UnitOfWorkFilter

 

public class UnitOfWorkFilter : ActionFilterAttribute
  {
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
      var unitOfWork = DependencyResolver.Current.GetService<IUnitOfWork>();
      unitOfWork.BeginTransaction();
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
      var unitOfWork = DependencyResolver.Current.GetService<IUnitOfWork>();
      unitOfWork.EndTransaction();
    }
  }
Code

How I fixed FluentNHibernate.Cfg.FluentConfigurationException on MVC 3

Just to let you know this may not solve your version of this error (since it’s so vague) but it’s how I solved it in one of my projects.

On a previous post I mention I was using NHibernate in one of the projects I’m working on and as such we’re using FluentNHibernate.

I’ve created a class (let’s call it SessionManager) that handles creating the ISessionFactory instance (and stores it in a static field). The project is built with MVC 3 and makes use of the DI provider along with Ninject so this code snippet should look familiar. (It’s where you set up you DI – usually the AppStart_NinjectMVC3)

kernel.Bind<ISessionFactory>().ToConstant(SessionManager.CreateSessionFactory());

That is the line the caused the problems; not sure how but the aspnet compiler dies. In the end I changed ninject to use “ToMethod” instead:

kernel.Bind<ISessionFactory>().ToMethod(c => SessionManager.CreateSessionFactory());

Since the session manager handles creating the ISessionFactory like I mentioned earlier we don’t get multiple instances of ISessionFactory.

Code

Asp.Net MVC 2 Routing SubDomains to Areas

I’ve been building an Asp.Net MVC 2 site with Tom on the new Thap site and we hit a stumbling point regarding sub-domains and areas; you can probably guess what the problem was from the title.

Any way after a bit of googling it looks like no one has figured this out, or that they arn’t sharing. So it’s time I shared the solution that worked for us. This requires no libraries or esoteric settings or anything like that, just a little bit of code that will end up making your routes look like this:

context.Routes.MapSubDomainRoute(
        "Admin_default", // Name
        "admin", // SubDomain
        "{controller}/{action}/{id}", // Url
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Defaults
        new[] { typeof(Controllers.HomeController).Namespace }); // Namespace

First we need to create a Route class that can handle subdomains, lucky for you I just happen to have one. What this class does is check the incoming request, if the sub-domain matches it then checks to see if the rest of the url matches the route you specified:

Update: Since publishing this post I’ve added an update to the code. The GetVirtualPath function  has been overridden to check if the area of the value matches the sub-domain . This was needed because it messed up the url generation for everything.

namespace Your.App
{
  using System.Web;
  using System.Web.Routing;

  /// <summary>
  /// A route class to work with a specific subDomain
  /// </summary>
  public class SubDomainRoute : Route
  {
    /// <summary>
    /// The subDomain to route against
    /// </summary>
    private readonly string subDomain;

    /// <summary>
    /// Initializes a new instance of the <see cref="SubDomainRoute"/> class.
    /// </summary>
    /// <param name="subDomain">The sub domain.</param>
    /// <param name="url">The URL.</param>
    /// <param name="routeHandler">The route handler.</param>
    public SubDomainRoute(string subDomain, string url, IRouteHandler routeHandler) : base(url, routeHandler)
    {
      this.subDomain = subDomain.ToLower();
    }

    /// <summary>
    /// Returns information about the requested route.
    /// </summary>
    /// <param name="httpContext">An object that encapsulates information about the HTTP request.</param>
    /// <returns>
    /// An object that contains the values from the route definition.
    /// </returns>
    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
      var url = httpContext.Request.Headers["HOST"];
      var index = url.IndexOf(".");

      if (index < 0)
      {
        return null;
      }

      var possibleSubDomain = url.Substring(0, index).ToLower();

      if (possibleSubDomain == subDomain)
      {
        var result =  base.GetRouteData(httpContext);
        return result;
      }

      return null;
    }

    /// <summary>
    /// Returns information about the URL that is associated with the route.
    /// </summary>
    /// <param name="requestContext">An object that encapsulates information about the requested route.</param>
    /// <param name="values">An object that contains the parameters for a route.</param>
    /// <returns>
    /// An object that contains information about the URL that is associated with the route.
    /// </returns>
    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
      // Checks if the area to generate the route against is this same as the subdomain
      // If so we remove the area value so it won't be added to the URL as a query parameter
      if(values != null && values.ContainsKey("Area"))
      {
        if(values["Area"].ToString().ToLower() == this.subDomain)
        {
          values.Remove("Area");
          return base.GetVirtualPath(requestContext, values);
        }
      }

      return null;
    }
  }
}

The next step we take is to create a bunch of extensions methods to make mapping the sub-domain a bit easier. I lifted this code straight from the MVC source and made a tiny adjustment.

namespace Your.App
{
  using System;
  using System.Diagnostics.CodeAnalysis;
  using System.Web.Mvc;
  using System.Web.Routing;

  public static class RouteCollectionExtensions
  {
    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
        Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapSubDomainRoute(this RouteCollection routes, string name, string subDomain, string url)
    {
      return MapSubDomainRoute(routes, name, subDomain, url, null /* defaults */, (object)null /* constraints */);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
        Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapSubDomainRoute(this RouteCollection routes, string name, string subDomain, string url, object defaults)
    {
      return MapSubDomainRoute(routes, name, subDomain, url, defaults, (object)null /* constraints */);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
        Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapSubDomainRoute(this RouteCollection routes, string name, string subDomain, string url, object defaults, object constraints)
    {
      return MapSubDomainRoute(routes, name, subDomain, url, defaults, constraints, null /* namespaces */);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
        Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapSubDomainRoute(this RouteCollection routes, string name, string subDomain, string url, string[] namespaces)
    {
      return MapSubDomainRoute(routes, name, subDomain, url, null /* defaults */, null /* constraints */, namespaces);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
        Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapSubDomainRoute(this RouteCollection routes, string name, string subDomain, string url, object defaults, string[] namespaces)
    {
      return MapSubDomainRoute(routes, name, subDomain, url, defaults, null /* constraints */, namespaces);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
        Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapSubDomainRoute(this RouteCollection routes, string name, string subDomain, string url, object defaults, object constraints, string[] namespaces)
    {
      if (routes == null)
      {
        throw new ArgumentNullException("routes");
      }
      if (url == null)
      {
        throw new ArgumentNullException("url");
      }
      if (subDomain == null)
      {
        throw new ArgumentNullException("subDomain");
      }

      Route route = new SubDomainRoute(subDomain, url, new MvcRouteHandler())
      {
        Defaults = new RouteValueDictionary(defaults),
        Constraints = new RouteValueDictionary(constraints)
      };

      if ((namespaces != null) && (namespaces.Length > 0))
      {
        route.DataTokens = new RouteValueDictionary();
        route.DataTokens["Namespaces"] = namespaces;
      }

      routes.Add(name, route);

      return route;
    }
  }
}

The final thing to do is set up your routes in the AreaRegistration class

context.Routes.MapSubDomainRoute(
        "Admin_default", // Name
        "admin", // SubDomain
        "{controller}/{action}/{id}", // Url
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Defaults
        new[] { typeof(Controllers.HomeController).Namespace }); // Namespace

Look familiar?

The namespace section is used to distinguish between Identically name controllers, so if you have a home controller in two areas that line will stop any conflicts.

There is one last item to take note of, when you create a new action in a controller of an area you’ll need to specify the location of the view. If your using the MvcContrib like we do then the T4MVC template comes in vary handy. All the Actions in the areas now look something like this:

    public virtual ActionResult Index()
        {
            return View(this.Views.Index);
        }

Or if you’re not using the T4MVC then this:

    public virtual ActionResult Index()
        {
            return View("~/Areas/Admin/Views/Home/Index.aspx");
        }
Code

Find the transparent pixels in an image – WPF

Extracted from: http://random.tonywilliams.me.uk/post/392778744/find-the-transparent-pixels-in-an-image-wpf

The other day I had to create an image element that contained a png with transparent sections and have it display a hand cursor when the mouse was over the opaque sections.

The first thing I tried (and failed) was to have an image element with the cursor property set to “Hand” like so:

<Image Source="{Binding SomeImage}" Cursor="Hand" />

That obviously never worked so I was forced to look at each individual pixel and see if it was transparent. What I ended up with was a function that generated a bunch of coordinates.

This is that function:

private static Dictionary<Point, object> FindTransparentPixelCoordinates(BitmapSource source)
{
  var points = new Dictionary<Point, object>();

  // Convert the source if the pixel format is not what we expect
  if (source.Format != PixelFormats.Bgra32)
  {
    source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0);
  }

  int width = source.PixelWidth;
  int height = source.PixelHeight;
  var bytes = new byte[width * height * 4];

  source.CopyPixels(bytes, width * 4, 0);

  var position = 0;

  for (var y = 0; y < height; y++)
  {
    for (var x = 0; x < width; x++)
    {
      var byteOffset = position;

      // The pixel format is stored as 32-bits (4 bytes) with the last byte being the alpha

      if (bytes[byteOffset + 3] == 0)
      {
        points.Add(new Point(x, y), null);
      }

      position += 4;
    }
  }

  return points;
}
Code

Serialising / Deserialising objects to Xml in .Net

Serialising / Deserialising objects to Xml: from my StackOverFlow

private static readonly Dictionary<Type, XmlSerializer> serialisers = new Dictionary<Type, XmlSerializer>();

/// <summary>Serialises an object of type T in to an xml string</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="objectToSerialise">Object to serialise</param>
/// <returns>A string that represents Xml, empty oterwise</returns>
public static string XmlSerialise<T>(this T objectToSerialise) where T : class, new()
{
  XmlSerializer serialiser;

  var type = typeof(T);
  if (!serialisers.ContainsKey(type))
  {
    serialiser = new XmlSerializer(type);
    serialisers.Add(type, serialiser);
  }
  else
  {
    serialiser = serialisers[type];
  }

  string xml;
  using (var writer = new StringWriter())
  {
    serialiser.Serialize(writer, objectToSerialise);
    xml = writer.ToString();
  }

  return xml;
}

/// <summary>Deserialises an xml string in to an object of Type T</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="xml">Xml as string to deserialise from</param>
/// <returns>A new object of type T is successful, null if failed</returns>
public static T XmlDeserialise<T>(this string xml) where T : class, new()
{
  XmlSerializer serialiser;

  var type = typeof(T);
  if (!serialisers.ContainsKey(type))
  {
    serialiser = new XmlSerializer(type);
    serialisers.Add(type, serialiser);
  }
  else
  {
    serialiser = serialisers[type];
  }

  T newObject;

  using (var reader = new StringReader(xml))
  {
    try { newObject = (T)serialiser.Deserialize(reader); }
    catch { return null; } // Could not be deserialized to this type.
  }

  return newObject;
}

When building the serialisation I had a help from an online example – but cannot remeber where it is…

Code

Single instance app in WPF 4 with argument passing

Extracted from: http://random.tonywilliams.me.uk/post/483779269/single-instance-app-in-wpf-4-with-argument-passing

I was building a WPF app that required the use of JumpLists; the thing with JumpLists is that it calls your app’s exe with an argument which in turn creates a new instance of your app.

After a quick bit of googling I found a link [now dead] some code that restricts an app to a signle instance by using a mutex and passes the command argument supplied via named pipes.

Only portions of the code was recoverable, the rest I created my self.

Note that the code uses the .Net 4 Tasks, this can be replaced with threads if you want to use it in .Net 3.5. This also only passes the first argument through but can be easily changed to pass multiple.

namespace Your.App
{
  using System;
  using System.IO;
  using System.IO.Pipes;
  using System.Threading;
  using System.Threading.Tasks;

  public class SingleInstance : IDisposable
  {
    private readonly bool ownsMutex;
    private Mutex mutex;
    private Guid identifier;

    /// <summary>
    /// Occurs when [arguments received].
    /// </summary>
    public event EventHandler<GenericEventArgs<string>> ArgumentsReceived;

    /// <summary>
    /// Initializes a new instance of the <see cref="SingleInstance"/> class.
    /// </summary>
    /// <param name="id">The id.</param>
    public SingleInstance(Guid id)
    {
      this.identifier = id;
      mutex = new Mutex(true, identifier.ToString(), out ownsMutex);
    }

    /// <summary>
    /// Gets a value indicating whether this instance is first instance.
    /// </summary>
    /// <value>
    /// 	<c>true</c> if this instance is first instance; otherwise, <c>false</c>.
    /// </value>
    public bool IsFirstInstance
    {
      get
      {
        return ownsMutex;
      }
    }

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose()
    {
      if (mutex != null && ownsMutex)
      {
        mutex.ReleaseMutex();
        mutex = null;
      }
    }

    /// <summary>
    /// Passes the arguments to first instance.
    /// </summary>
    /// <param name="argument">The argument.</param>
    public void PassArgumentsToFirstInstance(string argument)
    {
      using (var client = new NamedPipeClientStream(identifier.ToString()))
      using (var writer = new StreamWriter(client))
      {
        client.Connect(200);
        writer.WriteLine(argument);
      }
    }

    /// <summary>
    /// Listens for arguments from successive instances.
    /// </summary>
    public void ListenForArgumentsFromSuccessiveInstances()
    {
      Task.Factory.StartNew(() =>
                              {

                                using (var server = new NamedPipeServerStream(identifier.ToString()))
                                using (var reader = new StreamReader(server))
                                {
                                  while (true)
                                  {
                                    server.WaitForConnection();

                                    var argument = string.Empty;
                                    while (server.IsConnected)
                                    {
                                      argument += reader.ReadLine();
                                    }

                                    CallOnArgumentsReceived(argument);
                                    server.Disconnect();
                                  }
                                }
                              });
    }

    /// <summary>
    /// Calls the on arguments received.
    /// </summary>
    /// <param name="state">The state.</param>
    public void CallOnArgumentsReceived(object state)
    {
      if (ArgumentsReceived != null)
      {
        if (state == null)
        {
          state = string.Empty;
        }

        ArgumentsReceived(this, new GenericEventArgs<string>() { Data = state.ToString() });
      }
    }
  }
}

Here is the Generic Event Args class

namespace Your.App
{
  using System;

  public class GenericEventArgs<TEventDataType> : EventArgs
  {
    /// <summary>
    /// Gets or sets the data.
    /// </summary>
    /// <value>The data.</value>
    public TEventDataType Data { get; set; }
  }
}

To use this class create an instance with a GUID for your app like so:

private static readonly SingleInstance SingleInstance = new SingleInstance(new Guid("24D910A1-1F03-44BA-85A0-BE7BC2655FFE"));

Then on Application_Startup run your logic for it

private void Application_Startup(object sender, StartupEventArgs e)
{
  if (SingleInstance.IsFirstInstance)
  {
    SingleInstance.ArgumentsReceived += SingleInstanceParameter;
    SingleInstance.ListenForArgumentsFromSuccessiveInstances();
	// Do your other app logic
  }
  else
  {
    // if there is an argument available, fire it
    if (e.Args.Length > 0)
    {
      SingleInstance.PassArgumentsToFirstInstance(e.Args[0]);
    }

    Environment.Exit(0);
  }
}

static void SingleInstanceParameter(object sender, GenericEventArgs e)
{
  // Inform app of new arguments
}