Simon Green's Developer Blog
Developing .NET in the cold white north ...

Re-associate .aspx and .ascx files with the codebehind file

Saturday, 26 January 2008 12:26 by Simon

I recently inherited an application to work on which for whatever reason didn't have the code-behind files linked with the corresponding .aspx and .ascx files.

Visual studio looks for a codefile="class.cs" attribute in the page or control directive and this was missing.

So, when opening the application in Visual Studio the list of files was twice as long as it should have been and prevented Visual Studio from working some of it's magic like it does.

There were hundreds of files and editing each one to add the codefile="..." attribute to each page or control tag would have taken far too long.

What is the quickest way of turning this:

<%@ page language="c#" inherits="Company.Application.Class, Assembly" theme="Default" %>

... into this:

<%@ page language="c#" inherits="Company.Application.Class, Assembly" theme="Default" CodeBehind="Class.aspx.cs" %>

? Regular expressions of course !

Visual Studio can do search and replace and provides it own Regular Expression syntax that can be used (slightly different to most other versions strangely including the .NET framework itself but it works).

In case anyone needs to do this the syntax I used was:

Find what:
^{\<\%\@:bpage.+inherits=\"}{.+}\.{.+}\,{.+\"}{.+}$

Replace with:
\1\2.\3,\4 Codebehind="\3.aspx.cs"\5

Not forgetting to make sure that the 'Use:' option has 'Regular Expressions' selected.

Now, one click of the 'Replace All' button and the files were re-associated (after saving and re-opening the project).

For controls, I just replaced the 'page' part of the Find text with 'control'.

If you don't use a namespace then you may need to tweak the regex's a little but hopefully this should save you some work.


Stupid web trick - displaying an image without an image (Image2Html)

Saturday, 5 January 2008 13:00 by Simon

This is an old project I came across while seaching for a different project called Html2Image (which, given a URL would produce an image of the rendered page). I can only describe this as a 'stupid web trick' although there may be some uses for it. This one will take an image file and convert it to HTML.

Not to an HTML <img src="theimage.gif"/> tag though, to actual HTML - each pixel is an HTML element with the background color coming from a 'palette' of CSS styles. This is done to try and reduce the size of the generated XHTML and some RLE (Run Length Encoding) is also used to shrink repeated pixels of the same color to a single element entry in the output. For large images the output size will be prohibitive but for small images and icons it becomes more usable.

The net result is that you see the same image on the screen in the browser (or in an email client?) even if images are turned off. I did some experiments (again, several years ago) and it was possible to have richer-looking emails without needing images but again, things may have moved on and it may not be viable anymore.

The original project (at least 3 or 4 years years old) used <p> elements for each pixel but browsers must have moved on (and XHTML rendering is different to ye-olde-HTML) so I had to change the element tags to make it work again. It runs ok on IE and Safari but Mozilla / Firefox doesn't render it as it is (I honestly really don't know why people rave about it). I'm sure a bit of playing around with different element types and CSS attributes (line-height, font-size etc...) will produce something that runs. It may require different element types on different browsers (to cater for browsers that refuse to render empty elements and such like) but the approach will be the same.

Here are some screenshots of an example page which shows the same image displayed as a regular XHTML <img> tag and also as XHTML ...

Internet Explorer:

Safari:

Source Code: 

The VS.NET 2008 project is downloadable from the bottom of this post but here is the actual class that does the work and is usable in any version of the .NET runtime:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Text;

namespace InteSoft.Web.Utility
{
    public static class Image2Html
    {
        private const string containerElement = "div";
        private const string containerClass = "image";
        private const string pixelElement = "img";
        private const string pixelClassPrefix = "p";

        public static string Convert(string url)
        {
            if (null == url)
                throw new ArgumentNullException("url");

            if (url.Length == 0)
                throw new ArgumentException("url required", "url");

            Uri uri = new Uri(url);
            return Convert(uri);
        }

        public static string Convert(Uri url)
        {
            if (null == url)
                throw new ArgumentNullException("url");

            if (!url.IsAbsoluteUri)
                throw new ArgumentException("absolute url required", "url");
           
            WebClient wc = new WebClient();
            byte[] imgBytes = wc.DownloadData(url);
            MemoryStream imgStream = new MemoryStream(imgBytes);
            Bitmap bitmap = (Bitmap)Image.FromStream(imgStream);

            return Convert(bitmap);
        }

        public static string Convert(Bitmap bitmap)
        {
            if (null == bitmap)
                throw new ArgumentNullException("bitmap");

            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("<style>{0}.{1}{{line-height:1px;}}{0}.{1} {2}{{margin:0;padding:0;border:0;width:1px;height:1px;}}", containerElement, containerClass, pixelElement);
            ColorPalette colorPalette = bitmap.Palette;
            IDictionary<Color, int> paletteClassMap = new Dictionary<Color, int>(colorPalette.Entries.Length);
            for (int idx = 0; idx < colorPalette.Entries.Length; idx++)
            {
                Color color = colorPalette.Entries[idx];
                if (!paletteClassMap.ContainsKey(color))
                {
                    paletteClassMap.Add(color, idx);
                    sb.AppendFormat(".{0}{1:X2}{{background-color:#{2:X2}{3:X2}{4:X2};}}", pixelClassPrefix, idx, color.R, color.G, color.B);
                }
            }
            sb.AppendFormat("</style><{0} class=\"{1}\">", containerElement, containerClass);
            for (int y = 0; y < bitmap.Height; y++)
            {
                Color prevColor = bitmap.GetPixel(0, y);
                int count = 0;

                for(int x = 0; x < bitmap.Width; x++)
                {
                    Color color = bitmap.GetPixel(x, y);
                    count++;

                    if (color != prevColor || x == bitmap.Width - 1)
                    {
                        if (count == 1)
                        {
                            sb.AppendFormat("<{0} class=\"{1}{2:X2}\"/>", pixelElement, pixelClassPrefix, paletteClassMap[prevColor]);
                        }
                        else
                        {
                            sb.AppendFormat("<{0} class=\"{1}{2:X2}\" style=\"width:{3}px\"/>", pixelElement, pixelClassPrefix, paletteClassMap[prevColor], count);
                        }

                        prevColor = color;
                        count = 0;
                    }
                }
                sb.Append("<br/>");
            }

            sb.AppendFormat("</{0}>", containerElement);
           
            return sb.ToString();
        }
    }
}

Enjoy!

Download source: Image2Html.zip (8.23 kb)


Tags:  
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Ode to the MVC Framework

Sunday, 9 December 2007 13:36 by Simon

We've all been there ... thought we were going to get some code out of the door but then for one reason or another we couldn't manage it. I hope ScottGu et al who worked so hard to try and get it out this weekend don't take this the wrong way but here is a modified version of the lyrics to a song from the musical 'Les Miserables' for all of us who are sooo keen to get our hands on the new framework and waited all weekend for it ...

MVC framework (to 'Les Miserables - Empty Chairs At Empty Tables' music)

[A developer who got his hands on the MVC framework and blogged about it]

There's a grief that can't be spoken
There's a pain goes on and on
Empty pages, empty tables
Now my sites are dead and gone

Here they talked of view-controllers
Here it was they lit the flame
Here they sang about the framework
And the framework never came.

From a blog page in Seattle
They could see a world reborn
And they rose with voices ringing
I can hear them now!
The very code that they had posted
Became their last communion
On the lowly CTP...
At dawn.

Oh my friends, my friends forgive me.

[The ghosts of those who died waiting for the MVC framework appear.]

That I have code and you have none
There's a grief that can't be spoken
There's a pain goes on and on

Phantom frameworks run on windows
Mock assemblies on the floor
Databases with no tables
Where my view will run no more.

[The ghosts fade away.]

Oh my friends, my friends, don't ask me
What your sacrifice was for
Empty projects with no tables
Where my code will run no more...

Ah well, at least I have something to look forward to next week!!

Tags:   ,
Categories:   .NET | MVC
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

MVC Framework for ASP.NET

Sunday, 9 December 2007 04:02 by Simon

The ASP.NET 3.5 Extensions Preview (which includes microsoft's new MVC framework) should be release today on ASP.NET. It was due to ship earlier in the week but due to a bug got delayed. However, the team behind it have been working over the weekend to get it out. I can't wait to get my hands on it.

I've used ASP.NET for development even though I know about the other approaches (Ruby on Rails, Castle etc...) simply because I make a living out of coding and most clients want the big corporate supplied platform. Going into a company and trying to sell Ruby on Rails can be quite difficult and there simply aren't the opportunities / jobs about to justify switching to it (although I can understand people using it on private projects and startups).

Some question whether Microsoft should be producing a copy or clone of what existing open source projects already do. Well, I'm glad they are doing it!

Love em or hate em, Microsoft make some great development tools and platforms / frameworks and using these is how I make a living. 

What I think the ASP.NET MVC framework will do is validate the approach (if it needed it) and also allow it to be used in corporate / enterprise environments - i.e. it will become mainstream and less time will have to be spent selling it to people who really don't know the difference between a MVC and an MCP but don't want to risk their position by allowing some developer or consultant to lead them down the road to a minority used platform.

ScottGu has made some posts about what the MVC framework is and getting started with it which are a great read:

ASP.NET MVC Framework
ASP.NET MVC Framework (Part 1)
ASP.NET MVC Framework (Part 2): URL Routing
ASP.NET MVC Framework (Part 3): Passing ViewData from Controllers to Views
ASP.NET MVC Framework (Part 4): Handling Form Edit and Post Scenarios

Also, some other blog posts provide more detailed information about various aspects:

TDD and Dependency Injection with ASP.NET MVC
ASP.NET MVC Preview: Using The MVC UI Helpers

I can't wait to use this and already have some apps planned to use it ...

Tags:   ,
Categories:   .NET | MVC
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

NHibernate VistaDB Driver and Dialect

Friday, 7 December 2007 13:35 by Simon

Well, I finally got a bit of spare time and published the NHibernate driver and dialect for VistaDB as a CodePlex project.

As I mentioned in my previous blog entry, VistaDB is really useful even if you only use it during unit testing.

The really great thing about it though is that you can do normal database / NHibernate development and have a simple XCopy deployment which makes application demos very easy (complicated installs and configurations are often a barrier to evaluation and possible sales). Depending on your application and the usage that it gets VistaDB may or may not be up to the task of handling the persistence for the full deployment (it is a file-based database although a proper server version is on the way). With NHibernate though this isn't a worry as the customer is free to use any of the other supported database engines for the deployed version.

I intend to update a forum application I wrote a number of years ago to the new ASP.NET MVC about to be release and use the VistaDB database during development. The current SQL Server database is fairly large (about 4Gb) and has well over 2.5 million posts on it so it should give it a good test - I will let you know how I get on with it.

Tags:   , , ,
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

"Bad Request" error when using friendly URLs with special characters in ASP.NET

Sunday, 7 May 2006 16:45 by Simon

Our ASPRedirector.NET product can be used to re-write query-string URLs to friendly URLs with ID parameters converted to text. This is typically done for Search Engine Optimisation to improve page ranking because words appearing in the URL are taken into account by search engines. We have developed re-writing configuration rules for many eCommerce / shopping-cart software packages such as BV Software's BVCommerce and MediaChase's eFC.

However, if the category and / or product name contain certain reserved characters then you can run into a problem. Even if the characters such as $. %, ? are encoded correctly the page may not be returned and all you see is "bad request" (error 400). It isn't URLScan that is causing this though but the behavior of the ASP.NET ISAPI filter which doesn't pass the request on.

There is a Microsoft KB Article 826437 about the issue

The solution given is incorrect though and the correct registry key entry is shown below:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET]
  "VerificationCompatibility"=dword:00000001

This fixes the issue and allows you to have nice, optimised URLs on your eCommerce website - regardless of the characters in you category and product names.

 

Tags:   , ,
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Windows 2003 SP1 .NET Encoding Issue

Tuesday, 11 October 2005 16:31 by Simon

We recently came across an issue with one of our components (ASPRedirector.NET) where a customer who had installed Windows 2003 SP1 started getting errors on their website. The errors only happened if they used a certain encoding in the globalisation settings:


<globalization requestEncoding="iso-8859-15" responseEncoding="iso-8859-15"/>

The error being thrown was:

NotImplementedException: The method or operation is not implemented.
System.Web.CodePageNoBestFitEncoding.GetCharCount(Byte[] bytes, Int32 index, Int32 count)

If another encoding was used then everything worked fine (but they wanted to use this particular encoding)

Our component needed to use the encoder / decoder objects returned from Response.ContentEncoding in order to decode the bytes passed into a filter to look at the page content and encode them again so that any changes were output in the chosen encoding.

Creating a simple filter highlighted the problem:

public class Filter : Stream
 {
  private Encoder encoder;
  private Decoder decoder;
  private Stream baseStream;

  public Filter(HttpContext context)
  {
   Encoding encoding = context.Response.ContentEncoding;
   this.encoder = encoding.GetEncoder();
   this.decoder = encoding.GetDecoder();
   this.baseStream = context.Response.Filter;
  }

  public override bool CanRead
  {
   get { return false; }
  }

  public override bool CanWrite
  {
   get { return true; }
  }

  public override bool CanSeek
  {
   get { return false; }
  }

  public override void Close()
  {
   baseStream.Close();
  }

  public override void Flush()
  {
   baseStream.Flush();
  }

  public override long Length
  {
   get { throw new NotSupportedException(); }
  }

  public override long Seek(long offset, SeekOrigin origin)
  {
   throw new NotSupportedException();
  }

  public override void SetLength(long value)
  {
   throw new NotSupportedException();
  }

  public override long Position
  {
   get { throw new NotSupportedException(); }
   set { throw new NotSupportedException(); }
  }

  public override int Read(byte[] buffer, int offset, int count)
  {
   throw new NotSupportedException();
  }

  public override void Write(byte[] buffer, int offset, int count)
  {
   // get number of characters that the byte array will be decoded into
   int charCount = this.decoder.GetCharCount(buffer, offset, count);
   // create character array to hold them
   char[] chars = new char[charCount];
   // decode byte array into characters
   int charCountDecoded = decoder.GetChars(buffer, offset, count, chars, 0);

   // we now have characters and can process them
   // converting to a string should be the readable content
   string content = new string(chars);

   // get number of bytes that the character array will be encoded into
   int byteCount = encoder.GetByteCount(chars, 0, charCountDecoded, true);
   // create byte array to hold them
   byte[] bytes = new byte[byteCount];
   // encode character array into bytes
   int byteCountEncoded = encoder.GetBytes(chars, 0, charCountDecoded, bytes, 0, true);

   // write bytes to output stream - this should be exactly what came in
   baseStream.Write(bytes, 0, byteCountEncoded);
  }
 }

This fails if the responseEncoding is set to "iso-8859-15" after Windows 2003 SP1 has been applied but works before SP1 and if a different encoding is used (the default "utf-8" for instance).

So what's the problem? I found a lone post in a newsgroup that explained it:

SP1 of Windows Server introduced a new "feature" in the GlobalizationConfig class called EnableBestFitResponseEncoding.

Effect is that when you set anything other than UTF8 in web.config, e.g. <globalization requestEncoding="iso-8859-1" responseEncoding="iso-8859-1" />, many functions will break (including HttpUtility.URLDecode) with a MethodNotImplementedExecption in the new internal class CodePageNoBestFitEncoding.

Analyzing with the reflector reveals, that new code was added to the HttpResponse.ContentEncoding property:

                  if (!this._encoding.Equals(Encoding.UTF8))
                  {
                        string text1 = this._encoding.GetType().FullName;
                        if ((config1 == null) || !config1.EnableBestFitResponseEncoding)
                        {
                              if (text1 == "System.Text.MLangCodePageEncoding")
                              {
                                    this._encoding = Encoding.GetEncoding("mlang");
                              }
                              else if ((text1 == "System.Text.CodePageEncoding") || (text1 == "System.Text.Latin1Encoding"))
                              {
                                    int num1 = this._encoding.CodePage;
                                    this._encoding = new CodePageNoBestFitEncoding(num1);
                              }
                        }

Assuming that EnableBestFitResponseEncoding is false by default, this property will return a new instance of CodePageNoBestFitEncoding when you set a responseEncoding="iso-8859-1" in web.config.

Many of the normal Encoding methods in CodePageNoBestFitEncoding will throw the MethodNotImplemented exception which explains the above mentioned bahavior.

Some additional analysis reveals that there is a new attribute for <globalization > called "enableBestFitResponseEncoding". After setting this attribute to "true", everthing works again as normal with a responseEncoding other than UTF8.

A search in Microsoft's site for "enableBestFitResponseEncoding" returns 0 hits. Thank you Microsoft!

 

Tags:   , ,
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

NHibernate.Helper Project

Thursday, 7 July 2005 16:16 by Simon

When using NHibernate in an ASP.NET application it is important to manage sessions correctly. Typically, a session-per-request pattern is used with a single session created and used for the lifetime of a request and then discarded. This helper project makes using NHibernate with ASP.NET easier by automating the creation of sessions and ensuring that they are closed after each request. It also provides some convenient methods to make coding simpler and more readable:

Automatically create the database schema:

Db.CreateDatabase();
Load an object from the database

Customer customer = (Customer)Db.Load(typeof(Customer), 123);
Save an object:

Db.Save(Customer);
Delete an object:

Db.Delete(Customer);
Access to the NHibernate Configuration and SessionFactory objects are provided if needed.

Configuration
NHibernate already has a comprehensive and flexible configuration system where settings can be defined in code, in the web.config file or in a separate XML file. Using the separate XML file enables the location of the mapping files to be configured as required. The configuration below defines the NHibernate connection properties and driver classes to use (these could also be defined in the web.config file) and the location of the nhibernate mapping files (in this case the assembly 'MyAssembly' which would contain embedded resources).


<?xml version="1.0" encoding="utf-8" ?>

<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.0" >

 <session-factory name="chat">

  <!-- properties -->

  <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

  <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>

  <property name="connection.connection_string">Server=localhost;initial catalog=nhibernate;Integrated Security=SSPI</property>

  <property name="show_sql">false</property>

  <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>

  <property name="use_outer_join">true</property>

  <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>

  <!-- mapping files -->

  <mapping assembly="MyAssembly" />

 </session-factory>

</hibernate-configuration>

Rather than simply use the default filename "nhibernate.cfg.xml" I prefer instead to use "nhibernate.config", mainly because using an xml file extension is a security risk as the config file could easily be downloaded whereas access to the .config extension is restricted by ASP.NET automatically. To provide some extra flexibility the name of the file is specified in the <appSetting> section with the key "nhibernate.config":


<appSettings>

 <add key="nhibernate.config" value="~/nhibernate.config" />

</appSettings>


Now, the only other thing that needs to be added to the web.config file is the entry for the HttpModule:


<httpModules>

 <add name="NHibernateModule" type="NHibernate.Helper.Module, NHibernate.Helper" />

</httpModules> 

Here is the HttpModule itself. As you can see, it is extremly simple and simply closes the connection at the end of the request.

using System;
using System.Web;
namespace NHibernate.Helper
{
   /// <summary>    
   /// HttpModule to automatically close a session at the end of a request    
   /// </summary>    
   public sealed class Module : IHttpModule
   {
      public void Init(HttpApplication context)
      {
         context.EndRequest += new EventHandler(EndRequest);
      }
      public void Dispose() { }
      public void EndRequest(Object sender, EventArgs e)
      {
         Db.CloseSession();
      }
   }
}

The Db class contains all the helper methods and manages the creation and lifetime of the sessions (with the HttpModule above).

using System;
using System.Web;
using System.Configuration;
using NHibernate;
using NHibernate.Cfg;
namespace NHibernate.Helper
{    
   /// <summary>    
   /// Provides access to a single NHibernate session on a per request basis.    
   /// </summary>    
   /// <remarks>    
   ///        NHibernate requires mapping files to be loaded. These can be stored as    
   ///        embedded resources in the assemblies alongside the classes that they are for or    
   ///        in separate XML files.    
   ///        <br /><br />    
   ///        As the number of assemblies containing mapping resources may change and    
   ///        these have to be referenced by the NHibernate config before the SessionFactory    
   ///        is created, the configuration is stored in a separate config file to allow    
   ///        new references to be added. This would also enable the use of external mapping    
   ///        files if required.    
   ///        <br /><br />    
   ///        The name of the NHibernate configuration file is set in the appSettings section    
   ///        with the name "nhibernate.config". If not specified the the default value of    
   ///        ~/nhibernate.config is used.    
   ///        <br /><br />    
   ///        Note that the default config name is not used because the .xml extension is    
   ///        public and could be downloaded from a website whereas access to .config files is    
   ///        automatically restricted by ASP.NET.   
   /// </remarks>    
   public sealed class Db
   {        
      /// <summary>        
      /// Key used to identify NHibernate session in context items collection        
      /// </summary>       
      private const string sessionKey = "NHibernate.Db";        
     
      /// <summary>        
      /// NHibernate Configuration        
      /// </summary>       
      private static readonly Configuration configuration = new Configuration();       
     
      /// <summary>        
      /// NHibernate SessionFactory        
      /// </summary>        
      private static readonly ISessionFactory sessionFactory = configuration.Configure( HttpContext.Current.Request.MapPath(ConfigurationSettings.AppSettings["nhibernate.config"]) ).BuildSessionFactory();   
     
      /// <summary>      
      /// NHibernate Session. This is only used for NUnit testing (ie. when HttpContext    
      /// is not available.      
      /// </summary>
      private static readonly ISession session = sessionFactory.OpenSession();       
      /// <summary>    
      /// None public constructor. Prevent direct creation of this object.         
      /// </summary>        
      private Db() { }        
      /// <summary>        
      /// See beforefieldinit        
      /// </summary>        
      static Db() { }        
      /// <summary>        
      /// Creates a new NHibernate Session object if one does not already exist.        
      /// When running in the context of a web application the session object is        
      /// stored in HttpContext items and has 'per request' lifetime. For client apps        
      /// and testing with NUnit a normal singleton is used.        
      /// </summary>        
      /// <returns>NHibernate Session object.</returns>        
      [CLSCompliant(false)]        
      public static ISession Session        
      {
         get             
         {                 
            ISession session;                
            if (HttpContext.Current == null)                
            {                    
               session = Db.session;                
            }                
            else                
            {                    
               if (HttpContext.Current.Items.Contains(sessionKey))                
               {                    
                  session = (ISession)HttpContext.Current.Items[sessionKey];                 
               }             
               else            
               {                
                  session = Db.sessionFactory.OpenSession();    
                  HttpContext.Current.Items[sessionKey] = session;    
               }        
            }             
            return session;        
         }                        
      }
     
      /// <summary>        
      /// Closes any open NHibernate session if one has been used in this request.<br />        
      /// This is called from the EndRequest event.        
      /// </summary>        
      [CLSCompliant(false)]       
      public static void CloseSession()    
      {        
         if (HttpContext.Current == null)    
         {              
            Db.session.Close();  
         }     
         else          
         {               
            if (HttpContext.Current.Items.Contains(sessionKey))    
            {            
               ISession session = (ISession)HttpContext.Current.Items[sessionKey];  
               session.Close();    
               HttpContext.Current.Items.Remove(sessionKey);  
            }    
         }           
      }        
     
      /// <summary>        
      /// Returns the NHibernate Configuration object.        
      /// </summary>        
      /// <returns>NHibernate Configuration object.</returns>        
      [CLSCompliant(false)]     
      public static Configuration Configuration  
      {          
         get { return Db.configuration; }  
      }   
     
      /// <summary>        
      /// Returns the NHibernate SessionFactory object.        
      /// </summary>        
      /// <returns>NHibernate SessionFactory object.</returns>        
      [CLSCompliant(false)]        
      public static ISessionFactory SessionFactory      
      {          
         get { return Db.sessionFactory; }      
      }       
     
      /// <summary>        
      /// Loads the specified object.        
      /// </summary>        
      /// <param name="type">Type.</param>        
      /// <param name="id">Id.</param>
      public static void Load(System.Type type, object id)
      {          
         Db.Session.Load(type, id);  
      }        
     
      /// <summary>        
      /// Gets the specified object.        
      /// </summary>        
      /// <param name="type">Type.</param>        
      /// <param name="id">Id.</param>        
      public static object Get(System.Type type, object id)    
      {           
         return Db.Session.Get(type, id); 
      }        
     
      /// <summary>        
      /// Save object item using NHibernate.        
      /// </summary>        
      /// <param name="item">Object to save</param>        
      public static void Save(object item)     
      {           
         ITransaction transaction = Db.Session.BeginTransaction();   
         try        
         {              
            Db.Session.Save(item);   
            transaction.Commit();  
         }         
         catch (Exception ex)  
         {               
            transaction.Rollback(); 
            throw;         
         }   
      }        
     
      /// <summary>        
      /// Save object item using NHibernate.        
      /// </summary>        
      /// <param name="item">Object to delete</param>        
      public static void Delete(object item)      
      {         
         ITransaction transaction = Db.Session.BeginTransaction(); 
         try       
         {          
            Db.Session.Delete(item);   
            transaction.Commit();       
         }           
         catch (Exception ex)   
         {               
            transaction.Rollback();  
            throw;          
         }     
      }        
     
      /// <summary>        
      /// Creates the specified database.        
      /// </summary>        
      /// <param name="script">Script.</param>        
      /// <param name="export">Export.</param>        
      public static void CreateDatabase()     
      {           
         NHibernate.Tool.hbm2ddl.SchemaExport se = new NHibernate.Tool.hbm2ddl.SchemaExport(Db.Configuration);
         se.Create(true, true); 
      } 
   }
}

 

Tags:   ,
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed