Thursday, 18 November 2010

Show an image saved in a SQL Table on an ASP.Net Image Control

In a previous entry I have shown, how to store images to a database table. Now I will show you how to retrieve it and show it on a ASP.Net Image control. There is no straight forward method showing it like “ImageControl.Image = ImageStream….” How ever it can be achieved using a Generic Handler.

Add a ‘Generic Handler’ to your ASP.Net web application. And in this example I will name it as ‘getImageFromDB.ashx’. By default IHttpHandler will be implemented. (ProcessRequest and IsReusable methods will be implemented). And I will add another method called ‘GetImage’ and alter the ‘ProcessRequest’ method. And the finished handler should similar to this:

   1: using System;
   2: using System.Drawing;
   3: using System.Drawing.Imaging;
   4: using System.IO;
   5: using System.Web;
   6: using System.Data;
   7: using System.Data.SqlClient;
   8:  
   9: namespace MyWebApplication
  10: {
  11:    
  12:     public class getImageFromDB : IHttpHandler
  13:     {
  14:         public void ProcessRequest(HttpContext context)
  15:         {
  16:             context.Response.Clear();
  17:  
  18:             if (!String.IsNullOrEmpty(context.Request.QueryString["empID"]))
  19:             {
  20:                 int id = Int32.Parse(context.Request.QueryString["empID"]);
  21:  
  22:                 Image image = GetImage(id);
  23:  
  24:                 context.Response.ContentType = "image/jpeg";
  25:                 image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
  26:             }
  27:             else
  28:             {
  29:                 context.Response.ContentType = "text/html";
  30:                 context.Response.Write("<p>Need a valid id</p>");
  31:             }
  32:         }
  33:  
  34:         public bool IsReusable
  35:         {
  36:             get
  37:             {
  38:                 return false;
  39:             }
  40:         }
  41:  
  42:         private Image GetImage(int empID)
  43:         {
  44:  
  45:             MemoryStream memoryStream = new MemoryStream();
  46:             //Retrieve image from Database to a memeory stream. If you are using a different method, use it and assign the data to the 'memoryStream' variable.
  47:  
  48:             string connectionString = "Password=PWD;Persist Security Info=True;User ID=USER;Initial Catalog=SampleDatabase;Data Source=SQLSERVER";
  49:             using (SqlConnection sqlConnection = new SqlConnection(connectionString))
  50:             {
  51:                 using (SqlCommand sqlCommand = new SqlCommand("SELECT emp_id, emp_name, emp_image FROM Employee where emp_id = " + empID.ToString(), sqlConnection))
  52:                 {
  53:                     sqlConnection.Open();
  54:                     SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
  55:  
  56:                     if (sqlDataReader.HasRows)
  57:                     {
  58:                         sqlDataReader.Read();
  59:                         byte[] btImage = (byte[])sqlDataReader["emp_image"];
  60:  
  61:                         memoryStream = new MemoryStream(btImage, false);
  62:                     }
  63:                 }
  64:                 sqlConnection.Close();
  65:             }
  66:             return Image.FromStream(memoryStream);
  67:         }
  68:     }
  69: }

And you can call the handler and display the image, using the following syntax :



   1: private void GetImageFromDatabase(int empID)
   2: {
   3:     imageControl.ImageUrl = "getImageFromDB.ashx?empID=" + empID.ToString();
   4: }

Saving an image to a SQL Database Table

Sometimes it’s not the best of method, to store images in to the database, since it’ll take lot of database space. But there are times, that it’s the only option on your list.
To this sample I will be using the following SQL Table.
   1: CREATE TABLE [dbo].[Employee](
   2:     [emp_id] [int] NOT NULL,
   3:     [emp_name] [varchar](50) NOT NULL,
   4:     [emp_image] [image] NULL
   5: ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

When inserting data use the following syntax:


   1: string fileName = @"D:\MyImage.jpg";
   2: string connectionString = "Password=PWD;Persist Security Info=True;User ID=USER;Initial Catalog=DATABASE;Data Source=SQLSERVER";
   3: using (SqlConnection sqlConnection = new SqlConnection(connectionString))
   4: {
   5:  
   6:     FileInfo finfo = new FileInfo(fileName);
   7:  
   8:     byte[] btImage = new byte[finfo.Length];
   9:     FileStream fStream = finfo.OpenRead();
  10:  
  11:     fStream.Read(btImage, 0, btImage.Length);
  12:     fStream.Close();
  13:  
  14:  
  15:     using (SqlCommand sqlCommand = new SqlCommand("INSERT INTO Employee (emp_id, emp_name, emp_image) VALUES(@emp_id, @emp_name, @emp_image)", sqlConnection))
  16:     {
  17:  
  18:         sqlCommand.Parameters.AddWithValue("@emp_id", 2);
  19:         sqlCommand.Parameters.AddWithValue("@emp_name", "Employee Name");
  20:         SqlParameter imageParameter = new SqlParameter("@emp_image", SqlDbType.Image);
  21:         imageParameter.Value = btImage;
  22:  
  23:         sqlCommand.Parameters.Add(imageParameter);
  24:  
  25:  
  26:         sqlConnection.Open();
  27:         sqlCommand.ExecuteNonQuery();
  28:         sqlConnection.Close();
  29:     }
  30:  
  31: }

Wednesday, 17 November 2010

Changing App.config contents at runtime

Sometimes it is required to change the contents of ‘App.config’ file. Assume if we are allowing user to override things like taxrates, which we keep on the ‘App.config’.
On the App.config, we have a key ‘TaxRate’ which has the value ‘15’.
   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <appSettings>
   4:         <add key="TaxRate" value="15"/>
   5:     </appSettings>
   6: </configuration>

And we have to change it to ‘20’. We can use the following syntax:


   1: Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
   2: AppSettingsSection appSection = config.AppSettings;
   3:  
   4: appSection.Settings["TaxRate"].Value = "20";
   5: config.Save(ConfigurationSaveMode.Modified,false);
   6:  
   7: ConfigurationManager.RefreshSection("appSettings");
   8: string zVal = ConfigurationManager.AppSettings["TaxRate"];
**Please note : The changes are temporary, when running on debug mode. But will be permanent when run using the built application (Executable)

Monday, 15 November 2010

Using FileSystemWatcher to monitor multiple directories

In a previous example I have showed how to use ‘FileSystemWatcher’ class to monitor a directory. But there are times that we need to monitor multiple directories and if any changes are available, invoke a given method.

We can do that by using this method. First create a class. We’ll call this class ‘Watcher’

   1: public class Watcher
   2:     {
   3:  
   4:         public string Directory { get; set; }
   5:         public string  Filter { get; set; }
   6:  
   7:  
   8:         private Delegate _changeMethod;
   9:  
  10:         public Delegate ChangeMethod
  11:         {
  12:             get { return _changeMethod; }
  13:             set { _changeMethod = value; }
  14:         }
  15:         
  16:         FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
  17:  
  18:         public Watcher(string directory, string filter, Delegate invokeMethod)
  19:         {
  20:             this._changeMethod = invokeMethod;
  21:             this.Directory = directory;
  22:             this.Filter = Filter;
  23:         }
  24:  
  25:  
  26:         public void StartWatch()
  27:         {
  28:             
  29:             
  30:             fileSystemWatcher.Filter = this.Filter;
  31:             fileSystemWatcher.Path = this.Directory;
  32:             fileSystemWatcher.EnableRaisingEvents = true;
  33:  
  34:             fileSystemWatcher.Changed += new FileSystemEventHandler(fileSystemWatcher_Changed);
  35:         }
  36:  
  37:         void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
  38:         {
  39:             if (_changeMethod != null)
  40:             {
  41:                 _changeMethod.DynamicInvoke(sender, e);
  42:             }
  43:         }
  44:     }

And we can use it to monitor multiple directories as shown below (for this example I have used a console application and I am only considering the change event):



   1: class Program
   2:     {
   3:         delegate void invokeMethodDelegate(object sender, FileSystemEventArgs e);
   4:  
   5:         static void Main(string[] args)
   6:         {
   7:             
   8:             invokeMethodDelegate mymethod = new invokeMethodDelegate(InvokeMethod);
   9:             Watcher w1 = new Watcher(@"C:\Directory1", "*.*", mymethod);
  10:             w1.StartWatch();
  11:  
  12:             Watcher w2 = new Watcher(@"D:\Directory2", "*.*", mymethod);
  13:             w2.StartWatch();
  14:  
  15:             string zRetVal = Console.ReadLine();
  16:  
  17:            
  18:         }
  19:  
  20:         static  void InvokeMethod(object sender, FileSystemEventArgs e)
  21:         {
  22:             Console.WriteLine("Change in file {0}", e.FullPath);
  23:         }
  24:     }

Thursday, 4 November 2010

Passing parameters for dynamically created SQL queries

There are times that we need to create SQL queries dynamically and pass values to parameters. You can always assign values with a syntax similar to “… WHERE ColumnName = ‘ + @Value + ‘ and …”. But the disadvantage of using the above syntax is, that you have to provide correct formatting according the data type of the column.

This can be prevented using this type of solution. (Assume you have to get a count of records which matches a certain condition which will be provide outside the query)

 

   1: declare @Value            as nvarchar(50)
   2: declare @Sql            as nvarchar(100)
   3: declare @Parameters        as nvarchar(100)
   4: declare @Count            as int
   5:  
   6: set @Value = 'ValueX'
   7: set @Sql = 'set @Count = (select count(*) from TableName where ColValue = @Value)'
   8: set @Parameters = '@Count int output, @Value nvarchar(100)'
   9:  
  10: exec sp_executesql @Sql,@Parameters,@Count output,@Value
  11:  
  12: select @Count

Using ‘FileSystemWatcher’ class to monitor file system changes

 

The ‘FileSystemWatcher’ class is very useful when it comes to monitor a file system path for changes such as create, update and delete of directories/files.

Create an object from the FileSystemWatcher class. (You need to add the ‘System.IO’ namespace)

FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();






 






And set the following properties. For this example we will only consider about text files (.txt)




fileSystemWatcher.Filter = "*.txt";
fileSystemWatcher.Path = @"D:\";
fileSystemWatcher.EnableRaisingEvents = true;





 



And add the following event handlers and create events.




fileSystemWatcher.Created += new FileSystemEventHandler(fileSystemWatcher_Created);
fileSystemWatcher.Changed += new FileSystemEventHandler(fileSystemWatcher_Changed);
fileSystemWatcher.Deleted += new FileSystemEventHandler(fileSystemWatcher_Deleted);
fileSystemWatcher.Renamed += new RenamedEventHandler(fileSystemWatcher_Renamed);





And create the following events



 




static void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e) {
Console.WriteLine("{0} - {1}",e.ChangeType,e.FullPath);
}

static void fileSystemWatcher_Deleted(object sender, FileSystemEventArgs e) {
Console.WriteLine("{0} - {1}", e.ChangeType, e.FullPath);
}

static void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e) {
Console.WriteLine("{0} - {1}", e.ChangeType, e.FullPath);
}

static void fileSystemWatcher_Created(object sender, FileSystemEventArgs e) {
Console.WriteLine("{0} - {1}", e.ChangeType, e.FullPath);
}





 



Execute this and create, change, rename and delete a text file. And above mentioned events will be invoked.

Thursday, 30 September 2010

Design Patterns ~ Singleton Pattern using C#

It is considered as the simplest of patterns. Main objective of singleton pattern is to restrict the instantiation of a class to a singe object. It can be implemented like this.

public class Singleton {
private static Singleton _instance;

private Singleton() {

}

public static Singleton Instance {
get{
if(_instance == null){
_instance = new Singleton();
}
return _instance;
}
}
}

The above mentioned implementation has advantages and disadvantages. The main advantages are :



  1. Since the instance is created inside the ‘Instance’ property, the class can handle additional functionality like instantiating a subclass.

  2. Lazy Instantiation’ approach. That is, instantiation of the class is not performed, till an object asks for an instance. This will avoid instantiating unnecessary  singletons when the application starts.

And the main disadvantage of this approach is, that this is not ideal for multithreaded environments. If separate threads of execution enter the Instance property method at the same time, more that one instance of the Singleton object may be created. Each thread could execute the following statement and decide that a new instance has to be created.

if(_instance == null)

 


The most common and suitable solution to overcome this is to use the ‘Double-Check Locking’. This will keep separate threads from creating new instances of the singleton at the same time.

public class Singleton {
private static volatile Singleton _instance;
private static object syncRoot = new object();

private Singleton() {

}

public static Singleton Instance {
get{
if(_instance == null){
lock (syncRoot) {
if (_instance == null) {
_instance = new Singleton();
}
}
}
return _instance;
}
}
}
This method make sure that only one instance is created and only when the instance is required. Making the variable ‘volatile’ make sure that assignment to the instance variable completes before the instance variable can be accessed. And in order to avoid deadlocks it uses a separate object to lock on, rather than using the type itself.