Twitter Feed Popout byInfofru

Pray your Prayers

Let us ask a question to ourselves, What will happen to us ? are we really prepared ...........

How to pass parameters to the dynamically added user control

In this post, I will explain how you can pass parameter to the dynamically added (from code behind) User Control. Most of you might aware of how we can achieve this in web application project. Following is the code for that

   1: Dim objCon As Control = Page.LoadControl("~/Controls/MyControl.ascx")
   2: Ctype(objCon,MyControl).PropertyOne = "Test"
   3: Ctype(objCon,MyControl).PropertyTwo = "USAM"
   4: MyPanel.Controls.add(objCon)

Now what if you have a web site project which does not have the pre-compiled assemblies and you are no more able to access the class of your user control. That is what the sum of last two ays.

Here is how you can do that by using System.reflection.

   1: Dim objCon As Control = Page.LoadControl("~/Controls/MyControl.ascx")
   2: 'Creating Dynamic Assmebly which holds control
   3: Dim objAssembly As Assembly = Compilation.BuildManager.GetCompiledAssembly("~/Controls/MyControl.ascx")
   4: 'You should definately know the name of your user control class
   5: Dim objType As Type = objAssembly.GetType("Controls_MyControl")
   6:  
   7: 'Properties
   8: Dim objPropOne As PropertyInfo = objType.GetProperty("PropertyOne")
   9: Dim objPropTwo As PropertyInfo = objType.GetProperty("PropertyTwo")
  10:  
  11: 'Setting Value of Properties
  12: bjPropOne.SetValue(objCon, 1, Nothing)
  13: objPropTwo.SetValue(objCon, 13, Nothing)
  14:  
  15: 'Finally placing control on the page
  16: pnlCommentsCon.Controls.Add(objCon)

So in this way you can pass parameters to the dynamically added user control.  

Get Repeater Control Output in String

In this post I will share with you a small code snippet which will help you to get the repeater control output in string variable.

   1: Dim sb As New StringBuilder()
   2: Dim objHtml As New HtmlTextWriter(New System.IO.StringWriter(sb))
   3:  
   4: If dt.Rows.Count > 0 Then
   5:     Repeater1.DataSource = dt
   6:     Repeater1.DataBind()
   7: End If
   8:  
   9: Repeater1.RenderControl(objHtml)
  10: Return sb.ToString() 

 

Well, I have used a little trick here. The RenderControl method of repeater control can put all the HTML in HtmlTextWriter Object and from HtmlTextWriter Object we have simply dump the output the to the string builder. That’s it ….

Show Visitors Map On Your Website (Map Stats)

Geeks, have you ever think of displaying visitors map on your website or blog. My friend Al Pascual created a free tool that can integrate right in your website and start functioning. That tool is called Map Stats.The best thing about Map Stats is it is Open Source and will be soon available on Codeplex And integration is very very easy all you need to do is to copy/paste a single line of JavaScript.Here is how you can integrate it.
   1: <script type="text/javascript" src="http://mapstats.net/Stats.ashx?Width=300&Height=200"></script>
   
I recommend all the bloggers to have a look at that and use Map Stats as it is very handy yet very useful tool.

Storing/Retrieving Hierarchies In SQL Server Database

Hierarchies are one of the most important part of many applications. It can be in shape of categories, family tree, organization charts etc. Maintaining hierarchies in data source like XML is not a big deal but when it comes to the database like SQL Server which is consist of flat table in terms of storing data, then it become a challenge.To overcome this (which I am sure most of us did ), we use recursion. Implementing recursion is very easy and can be applied on both back-end (by using cursors) and front-end. But yet recursive operation can be a great mess if hierarchy grow larger. Lots of repetitive quires and n number of database connection can make your application way slow.So, the idea of the moment is to use the hierarchical data without using recursion. while searching for the solution I came across “Storing Hierarchical Data in a Database” by Gijs Van Tulder. In this article, the Dutch guy mention two method for the processing of Hierarchal data. One is the same recursion which we have discussed above and the other one is ‘modified preorder tree traversal' algorithm.
Modified preorder tree traversal :
To make you understand better let me quote what he mention in his article.We'll start by laying out our tree in a horizontal way. Start at the root node (‘Food'), and write a 1 to its left. Follow the tree to ‘Fruit' and write a 2 next to it. In this way, you walk (traverse) along the edges of the tree while writing a number on the left and right side of each node. The last number is written at the right side of the ‘Food' node. In this image, you can see the whole numbered tree, and a few arrows to indicate the numbering order.sitepoint_numberingWe'll call these numbers left and right (e.g. the left value of ‘Food' is 1, the right value is 18). As you can see, these numbers indicate the relationship between each node. Because ‘Red' has the numbers 3 and 6, it is a descendant of the 1-18 ‘Food' node. In the same way, we can say that all nodes with left values greater than 2 and right values less than 11, are descendants of 2-11 ‘Fruit'. The tree structure is now stored in the left and right values. This method of walking around the tree and counting nodes is called the ‘modified preorder tree traversal' algorithm.Sources : http://www.sitepoint.com/article/hierarchical-data-database/2/Note : Let me keep myself honest, the above two paragraphs and image is by Gijs Van Tulder so He deserve the credit of this content. I am just sharing the T/SQL implementation of this algorithm.I again strongly recommend you to read the article completely  before going onward.

Schema :

Ok to start, lets create a following tabletblCommentsID is of course the primary key, where as comments is the simple text. Left and Right are the indexes of the child records where as level will show us at what level this node belongs to. so that we can set the tab index and indentation where as Entity Id is to group the nodes because in this table hundred different nodes set. So in short, Entity Id is to separate the different node set in a single table.Following is the script of the table
   1: CREATE TABLE [dbo].[tblComments](
   2:     [Id] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
   3:     [Comments] [nvarchar](2000) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
   4:     [Left] [int] NULL,
   5:     [right] [int] NULL,
   6:     [Level] [int] NULL,
   7:     [EntityId] [int] NULL,
   8:  CONSTRAINT [PK_tblComments] PRIMARY KEY CLUSTERED
   9: (
  10:     [Id] ASC
  11: )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
  12: ) ON [PRIMARY]

Add Record:

Now to add the record in this table, lets have a look at the following procedure
   1: CREATE PROCEDURE [dbo].[InsertComments]
   2:     @Comments nvarchar(2000),
   3:     @EntityId int,
   4:     @ParentId int = null
   5: AS
   6: BEGIN
   7:     Declare @Left int
   8:     Declare @Right int
   9:     Declare @Level int
  10:     declare @RightParent int
  11:     declare @rightParentOrig int
  12:     declare @leftParentOrig int
  13:
  14:     set @RightParent = null
  15:
  16:     if @ParentId is null
  17:     begin
  18:         set @Left = 1
  19:         set @Right = 2
  20:     end
  21:     else
  22:     begin
  23:         select @rightParentOrig = [right],@leftParentOrig =[left] , @Right = [right] + 1,@Left=[right],@Level=[Level]+1 from tblComments where id = @ParentId
  24:         set @RightParent =  @Right  + 1
  25:     end
  26:
  27:     UPDATE tblcomments
  28:     set
  29:     [right] = [right] + 2,
  30:     [left] = [left] + 2
  31:     where
  32:     [left] >=  @Left and entityId = @EntityId
  33:
  34:     UPDATE tblcomments
  35:     SET
  36:     [right] = [right] + 2
  37:     WHERE [left] < @leftParentOrig and [right] > @rightParentOrig
  38:
  39:     INSERT INTO [tblComments]([Comments],[Left],[right],[Level],[EntityId])
  40:      VALUES
  41:            (@Comments,@Left,@Right,@Level,@EntityId)
  42:
  43:     if @RightParent is not null
  44:         update tblComments set [right] = @RightParent where id = @ParentId
  45:
  46: END
Ok, now let me define the code line by lineFirst 15 : Well, these lines are quit easy to understand, we have declared some variables which we will use in next lines.Line no 16-24 : We are checking if the ParentId is null, then of course the node is the parent it self, that is why setting left to 1 and right to 2. But when the parent is specified, we need to set the right and left value according to the parent (+1 of the parent) and also need to +1 the level.Line no 27-37 : Consider a situation, where you have a tree completed and you want to add a node in the middle of the tree. These are the lines for that. Here, we are Creating space of the node by increasing the left and right values of the sibling nodes.Line no 39: This is the simple insert statement, where we are adding our record to the table with calculated right and left.Line no 43: In this statement, we are updating the right side of the parent node.Now Add some records using the above procedures, and do the select as following

Select Records:

   1: select * from tblComments where EntityId = 1
   2: order by [left] ,[right]
   3: -- 2nd option
   4: select * from tblComments where [left] >= 1 and [right] <= 10 and EntityId = 1
   5: order by [left] ,[right]
Both the above query will return the following result set.tblcommentsresultNow you can see the first record i.e id=30 is the parent record. So, the left value is 1 and the right is 10 and the level is 1. where as when you see the second record, it is the child of the first record that is why level is 2 and left is +1 greater then the parent and because all the records up to id=35 are it’s child so it has right index +1 greater then the last child.Now if you want to see the child of id=32 you can do as follows
   1: declare @left int,
   2: @right int,
   3: @EntityId int
   4:
   5: select @left= [left],  @right= [right],@EntityId =  EntityId from tblComments where Id = 32
   6:
   7: select * from tblComments where [left] >= @left and [right] <= @right and EntityId = @EntityId
   8: order by [left] ,[right]
In this way, you can exactly see the child nodes of each node.

Delete Records:

Now, lets see how can we remove the record from this table as hierarchy is depend upon the left and right index.
   1: CREATE PROCEDURE [dbo].[DeleteComments]
   2:     @CommentId int
   3: AS
   4: BEGIN
   5: Declare @Left int
   6: Declare @Right int
   7: declare @EntityId int
   8:
   9: select @Left = [left], @Right = [right], @EntityId = [EntityId] from tblComments
  10: where id = @CommentId
  11:
  12:
  13: delete from tblComments
  14: where id = @CommentId
  15:
  16: update tblComments
  17: set [left] = [left] - 2,
  18: [right] = [right] - 2
  19: where [left] >= @Left and entityId = @EntityId
  20:
  21:
  22: UPDATE tblcomments
  23:     SET
  24:     [right] = [right] - 2
  25:     WHERE [left] < @Left and [right] > @Right
  26:
  27: END
In Line no 9-10 : we are storing the left, right and entity of the record that will be deleted.In Line no 13-14 : delete the record from table.In Line no 16- end: updating the right and left values of the parent and sibling nodes by –2.

Conclusion:

This way, we can easily achieve the task of Hierarchal data without recursion. One more time, with full respect I like to give all the credit to Gijs Van Tulder. I have just made small modification in this to make it work according to me to.

Saving and Retrieving File Using FileStream SQL Server 2008

FileStream data type is a very important feature of SQL Server 2008 and gradually getting popular amongst developer for it’s feasibility. And in the past few days specially after “Configure SQL Server 2008 for File Stream” post. I received several feedbacks regarding the usage of FileStream with Ado.net and Frankly there is not much stuff available on Google for this topic.

In this post, I will guide you to use FileStream Data type in Ado.net. But before we start make sure you have configure your SQL Server 2008 instance to use File Stream Data type and for this you can read this post.

Once you finish with the Configuration execute the following script

   1: CREATE TABLE [dbo].[tbl_Files](
   2:     [Id] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
   3:     [SystemNumber] [int] NOT NULL,
   4:     [SystemFile] [varbinary](max) FILESTREAM  NULL,
   5:     [FileType] [varchar](5) NULL,
   6: UNIQUE NONCLUSTERED 
   7: (
   8:     [Id] ASC
   9: )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  10: ) ON [PRIMARY] FILESTREAM_ON [FileStreamGroup1]
  11:  
  12: GO
  13:  
  14: ALTER TABLE [dbo].[tbl_Files] ADD  CONSTRAINT [DF_tbl_Files_Id]  DEFAULT (newid()) FOR [Id]

This will create a table with FileStream Data type. Notice the FileType field I have used here to determine the type of file which we will use when we were downloading the file.

Now that we have created a table, lets now move on to the Stored Procedures by which we will access this newly created table.

Security Setting:

Don’t get confused with the heading, there is no additional setting required. You need to do one of the two available options. Either you need to specify “Integrated Security = true” in Connection String or you need to implement Asp.net Impersonation. It is there because SQL Server 2008 will not allow un authenticated user or instance to read/modify the file.

Most of the developers usually aware of Integrated Security stuff but let me give a little detail about asp.net impersonation. Actually, it is a way to Authorize the Instance of your asp.net application on SQL Server by using Credential Information.

Following links will help you to understand or implement impersonation.

http://blogs.msdn.com/shawnfa/archive/2005/03/21/400088.aspx
http://blogs.msdn.com/saurabhkv/archive/2008/05/29/windowsidentity-impersonation-using-c-code.aspx
http://www.west-wind.com/WebLog/posts/1572.aspx

Add Procedure:

Lets create a procedure call it “”FileAdd” and past the following script.

   1: Create PROCEDURE [dbo].[FileAdd]
   2: @SystemNumber int,
   3: @FileType varchar(5),
   4: @filepath varchar(max) output
   5: AS
   6: BEGIN
   7:     -- SET NOCOUNT ON added to prevent extra result sets from
   8:     -- interfering with SELECT statements.
   9:     SET NOCOUNT ON;
  10:  
  11:     DECLARE @ID UNIQUEIDENTIFIER
  12:     SET @ID = NEWID()
  13:  
  14:     INSERT INTO [dbo].[tbl_Files]
  15:     ([Id],[SystemNumber],SystemFile,FileType)
  16:     VALUES (@ID ,@SystemNumber,CAST('' AS VARBINARY(MAX)),@FileType)
  17:     
  18:     select @filepath = SystemFile.PathName() from tbl_Files where Id = @ID
  19:  
  20:     
  21:  
  22: END

In the above procedure, we add new records in our table and just pass empty (null) to the FileStream field because we first want our SQL Server to create an empty file on NTFS location which we can access from our code behind by using the path which we have taken as Output Parameter here.

notice the SystemFile.PathName(), it is a new function introduced in SQL Server 2008 which will return the NTFS location of the file.

 

Get Procedure:

Create a procedure and call it “FileGet”

   1: CREATE PROCEDURE [dbo].[FileGet]
   2: @Id varchar(50)
   3: AS
   4: BEGIN
   5:      select  SystemFile.PathName(),FileType from tbl_Files where Id = @ID
   6: END

This is a simple stuff, we are returning PathName and FileType by specifying ID. Just to read the record.

Upload and Store:

To save the file in the file stream, we will use FileUpload control to upload the file and then save it to FileStream field. For that we have created a page and drag FileUpload control with an Upload button.

Now on the click event of the button write the following code.

   1: byte[] buffer = new byte[(int)FileUpload1.FileContent.Length];
   2: FileUpload1.FileContent.Read(buffer, 0, buffer.Length);
   3:  
   4:  
   5: if (FileUpload1.FileContent.Length > 0)
   6: {
   7:     SqlConnection objSqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
   8:     objSqlCon.Open();
   9:     SqlTransaction objSqlTran = objSqlCon.BeginTransaction();
  10:  
  11:     SqlCommand objSqlCmd = new SqlCommand("FileAdd",objSqlCon,objSqlTran);
  12:     objSqlCmd.CommandType = CommandType.StoredProcedure;
  13:  
  14:     SqlParameter objSqlParam1 = new SqlParameter("@SystemNumber", SqlDbType.Int);
  15:     objSqlParam1.Value = "1";
  16:  
  17:     SqlParameter objSqlParam2 = new SqlParameter("@FileType", SqlDbType.VarChar,4);
  18:     objSqlParam2.Value = System.IO.Path.GetExtension(FileUpload1.FileName);
  19:  
  20:     SqlParameter objSqlParamOutput = new SqlParameter("@filepath", SqlDbType.VarChar, -1);
  21:     objSqlParamOutput.Direction = ParameterDirection.Output;
  22:  
  23:     objSqlCmd.Parameters.Add(objSqlParam2);
  24:     objSqlCmd.Parameters.Add(objSqlParam1);
  25:     objSqlCmd.Parameters.Add(objSqlParamOutput);
  26:  
  27:  
  28:     objSqlCmd.ExecuteNonQuery();
  29:  
  30:     string Path = objSqlCmd.Parameters["@filepath"].Value.ToString();
  31:  
  32:     objSqlCmd = new SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()", objSqlCon, objSqlTran);
  33:  
  34:     byte[] objContext = (byte[])objSqlCmd.ExecuteScalar();
  35:     
  36:  
  37:     SqlFileStream objSqlFileStream = new SqlFileStream(Path, objContext, FileAccess.Write);
  38:     
  39:     objSqlFileStream.Write(buffer, 0, buffer.Length);
  40:     objSqlFileStream.Close();
  41:  
  42:     objSqlTran.Commit();

Well, in the first two lines we have saved the uploaded file in byte and call this variable “buffer”.
As we are simply using ADO.net, that is why in line 7 and 8 we have created and open a connection. Where as it is worth to mention here, we need to use transaction when we want to do any operation on FileStream field that is why we have begin a new transaction in line no 9.

On line number 11 to 30, we have a simply setup command object and parameter stuff and then execute the procedure and save the output parameter in a variable called “Path”.

This new variable will contain the NTFS location of the file which is stored on SQL Server FileStream. It should be clear that, this file is empty yet as we have not stored any thing in it.

Now on line number 32 we have reused command object and this time we are executing a simple statement “GET_FILESTREAM_TRANSACTION_CONTEXT”. It is also a newly added feature in SQL Server 2008 which will return current transaction context to be used in the next few lines. Now, on line number 34 we have stored the output of the above statement in byte.

In line number 37, here is some thing new which is called “SqlFileStream”. It is a new class which you can find under “System.Data.SqlTypes”. It seems more like FileStream of “System.IO” but it should be cleared here that the file stored in FileStream field cannot be access using regular file stream object of “System.IO” we need to use SqlFileStream to access those files which are stored in FileStream field.

In line no 39 and on, we are writing the file with the content of uploaded file (Remember we have stored our uploaded file in bytes and call it “buffer”). and that’s it.

Read The Stored File:

We have finished with storing the file, now lets see how can we read this file back. To do this, Drag a Grid View and make it similar to the following

   1: <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
   2:        onrowcommand="GridView1_RowCommand">
   3:        <Columns>
   4:            <asp:BoundField DataField="ID" HeaderText="ID" />
   5:            <asp:BoundField DataField="SystemNumber" HeaderText="System Id" />
   6:            <asp:TemplateField>
   7:                <ItemTemplate>
   8:                    <asp:LinkButton ID="lbGetFile" runat="server" CommandName="GetFile" CommandArgument='<%#Eval("ID") %>' Text="Get File"></asp:LinkButton>
   9:                </ItemTemplate>
  10:            </asp:TemplateField>
  11:        </Columns>
  12:    
  13:    </asp:GridView>

And bind the GridView using the following code.

   1: protected void bindData()
   2: {
   3:     SqlConnection objSqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
   4:     objSqlCon.Open();
   5:  
   6:     SqlCommand objSqlCmd = new SqlCommand("Select * from tbl_Files", objSqlCon);
   7:     SqlDataAdapter objSqlDat = new SqlDataAdapter(objSqlCmd);
   8:     DataTable objdt = new DataTable();
   9:     objSqlDat.Fill(objdt);
  10:  
  11:     GridView1.DataSource = objdt;
  12:     GridView1.DataBind();
  13: }

Well, the above markup and the code is enough self explaining but the little important stuff to mention here is the link button. We will use the same link button to download the stored file. Lets quickly move on to the RowCommand implementation of the GridView.

   1: protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
   2: {
   3:     if (e.CommandName == "GetFile")
   4:     {
   5:  
   6:         SqlConnection objSqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
   7:         objSqlCon.Open();
   8:         SqlTransaction objSqlTran = objSqlCon.BeginTransaction();
   9:  
  10:         SqlCommand objSqlCmd = new SqlCommand("FileGet", objSqlCon, objSqlTran);
  11:         objSqlCmd.CommandType = CommandType.StoredProcedure;
  12:  
  13:         SqlParameter objSqlParam1 = new SqlParameter("@ID", SqlDbType.VarChar);
  14:         objSqlParam1.Value = e.CommandArgument;
  15:  
  16:         objSqlCmd.Parameters.Add(objSqlParam1);
  17:         string path = string.Empty;
  18:         string fileType = string.Empty;
  19:  
  20:         using (SqlDataReader sdr = objSqlCmd.ExecuteReader())
  21:         {
  22:             while (sdr.Read())
  23:             {
  24:                 path = sdr[0].ToString();
  25:                 fileType = sdr[1].ToString();
  26:             }
  27:             
  28:         }
  29:         
  30:         objSqlCmd = new SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()", objSqlCon, objSqlTran);
  31:  
  32:         byte[] objContext = (byte[])objSqlCmd.ExecuteScalar();
  33:  
  34:  
  35:         SqlFileStream objSqlFileStream = new SqlFileStream(path, objContext, FileAccess.Read);
  36:  
  37:         byte[] buffer = new byte[(int)objSqlFileStream.Length];
  38:         objSqlFileStream.Read(buffer, 0, buffer.Length);
  39:         objSqlFileStream.Close();
  40:  
  41:         objSqlTran.Commit();
  42:         Response.AddHeader("Content-disposition", "attachment; filename=" + Path.GetFileName(path) + fileType);
  43:         // Here you need to manage the download file stuff according to your need
  44:         Response.ContentType = "application/octet-stream";
  45:  
  46:         Response.BinaryWrite(buffer);
  47:  
  48:  
  49:         
  50:     }
  51: }

Well, in the first 8 lines, we have created and opened a connection and then begin the transaction. from line no 10 to 28, we are setting the parameter stuff, executing the procedure and save the output in the two variable called “path” and “fileType”.

In line no 30 to 32, we are executing the the transaction context statement and then save the output the bytes. (Same we have done when we were writing the file)

In line no 35 to 40, we have used the same SqlFileStream and instead of writing, we are reading the file this time(notice line no 38) and save the content of the file to the bytes. Now we have file content in bytes, So we have now commit the transaction in line no 41.

In line no 42 and 44, we are setting the content type and specifying the file name with the extension. That is why, we have also saved file type in the database so that at the time of downloading we can make it available in its original state.

And in line no 46, we are simply writing the binary of the file to the browser so that it can be downloaded.

Conclusion:

I have tried my best to explain the integration of FileStream field with ADO.net, and I found this is an easy way to accomplish the task. You can download the VS 2008 solution which contain the complete source code along with procedures and table SQL.

Since, it is a new featured in SQL Server 2008 which is still in CTP by the time I am posting this stuff that is why we can expect some modifications in the method of reading and saving files using FileStream. If somebody face any challenge in the above code. Please feel to contact me.

Get Column name From Stored Procedure

The requirement of the day is to extract the name of the columns returned by procedures. Stored Procedures are dynamic that is why we need to create a function that takes Stored Procedure name as parameter and return the column names in string. So here is the quick snippet for that

   1: Public Shared Function getMetaData(ByVal spName As String) As String()
   2:        Dim sqlCon As New SqlConnection(ConfigurationManager.ConnectionStrings("lmString").ConnectionString)
   3:        sqlCon.Open()
   4:  
   5:        Dim sqlCmd As New SqlCommand("sp_helptext " + spName, sqlCon)
   6:        Dim sqlDataAdapter As New SqlDataAdapter(sqlCmd)
   7:        Dim dt As New DataTable
   8:        Dim strTempQuery As String = String.Empty
   9:        Dim strColumns As String()
  10:        Dim strCol As String = String.Empty
  11:  
  12:        sqlDataAdapter.Fill(dt)
  13:        If dt.Rows.Count > 0 Then
  14:            For Each dr As DataRow In dt.Rows
  15:                strTempQuery += dr.Item(0)
  16:            Next
  17:        End If
  18:  
  19:        If Not strTempQuery = "" Then
  20:  
  21:            'Dim objRegex As New Regex("select([^<]*)from")
  22:  
  23:  
  24:            Dim objMatches As MatchCollection = Regex.Matches(strTempQuery, "select([^<]*)from", RegexOptions.IgnoreCase)
  25:  
  26:            For Each mymatch As Match In objMatches
  27:                strCol += mymatch.Groups(1).Value
  28:            Next
  29:  
  30:            If Not strCol = "" Then
  31:                strColumns = strCol.Split(",")
  32:                For a As Integer = 0 To strColumns.Length - 1
  33:                    strColumns(a) = strColumns(a).Trim()
  34:                Next
  35:            End If
  36:        End If
  37:        Return strColumns
  38:    End Function

 

Restriction : Though, we have achieved the target, but since we have used sp_helptext to extract the Stored Procedure data that is why it is not possible to process encrypted stored procedure.

Will make it more better in the future to accommodate all type of Stored Procedures.

Hello world from iphone

Hello world from iphone, this a kind of test post from wordpress client for iphone. Finally, after re installing the client I am now able to do post from my iphone. Cheers everyone

Integrating CSS Control Adapter With Menu Control

This is on the request of some of my readers to show how effective Asp.net menu control is by using CSS Control Adapter. Most of the folks either have no idea of what CSS Adapter is or have some problem in integrating that with their applications.

So, In this post I will brief you guys how can we use CSS Adapter to format the design of Asp.net Menu Control. Before we start, let me dig out why would somebody use CSS Adapter and what does that do ?

Have you ever notice by viewing the source of your page what asp.net runtime engine generate when you use any Data list, or in our case Menu Control.
It generates Table based layout, which is of course really difficult to design and not consider a good practice in the new web standards. To overcome that issue CSS Control Adapter is the answer. It will rendered div and unorderlist (UL) instead of table which can easily be redesign using CSS. It means, you can now have standardized approach to create web based controls. If you want to see what CSS Control Adapter provide you, Click Here and notice the HTML Snippet given at bottom. 

Ok, to start off lets download the source code and open the project. By the time I am writing this post only VS 2005 version of CSS Control Adapter is available. But that is  not an issue, If you are using VS 2008, simply convert the project. Even if you don’t want to open the project it still have no problem as we only need to copy paste some stuff from here.

Create A Web Application or Web Site Project in which you want to implement Menu Control. right click on your project and add special folder called App_Browser. Now Right Click on the newly created folder and Add Browser File and Name it “CSSFriendlyAdapters.browser”.

You can either write the following stuff in it or Just Copy / Paste this from CSS Control Adapter Project which you have downloaded before.

   1: <browsers>
   2:   <browser refID="Default">
   3:     <controlAdapters>
   4:       <adapter controlType="System.Web.UI.WebControls.Menu"
   5:                adapterType="CSSFriendly.MenuAdapter" />
   6:   
   7:     </controlAdapters>
   8:   </browser>
   9:  
  10:   <browser id="W3C_Validator" parentID="default">
  11:     <identification>
  12:       <userAgent match="^W3C_Validator" />
  13:     </identification>
  14:     <capabilities>
  15:       <capability name="browser"              value="W3C Validator" />
  16:       <capability name="ecmaScriptVersion"    value="1.2" />
  17:       <capability name="javascript"           value="true" />
  18:       <capability name="supportsCss"          value="true" />
  19:       <capability name="supportsCallback"     value="true" />
  20:       <capability name="tables"               value="true" />
  21:       <capability name="tagWriter"            value="System.Web.UI.HtmlTextWriter" />
  22:       <capability name="w3cdomversion"        value="1.0" />
  23:     </capabilities>
  24:   </browser>
  25: </browsers>

If you see the browser file available in CSS Control Adapter project you will realize that under ControlAdapter tag there are several other ControlType specified. But in our case as we are only using Menu Control so we have removed the un wanted stuff.

Now once you have done this, you need to add reference to the CSS Adapter. You can find the assembly in CSS Control Adapter Project.

Lets create a page and drop and Menu control. See the following snippet.

 

   1: <asp:Menu ID="Menu1" runat="server" Orientation="Horizontal" CssSelectorClass="SimpleEntertainmentMenu">
   2:      <Items>
   3:          <asp:MenuItem Text="Item 1" Value="Item 1">
   4:              <asp:MenuItem Text="Item a" Value="Item a">
   5:                  <asp:MenuItem Text="Item a - a" Value="Item a - a"></asp:MenuItem>
   6:              </asp:MenuItem>
   7:              <asp:MenuItem Text="Item B" Value="Item B"></asp:MenuItem>
   8:          </asp:MenuItem>
   9:          <asp:MenuItem Text="Item 2" Value="Item 2">
  10:              <asp:MenuItem Text="Item a" Value="Item a"></asp:MenuItem>
  11:          </asp:MenuItem>
  12:      </Items>
  13:  </asp:Menu>


Now we need to create a CSS file and linked that with the page we have created. The CSS File should like as below

   1: .SimpleEntertainmentMenu ul.AspNet-Menu /* Tier 1 */
   2: {
   3:     width: 13em; /* This is more than (6em x 2) because we want to leave room for borders around the <li> elements that are selected */
   4: }
   5:  
   6: .SimpleEntertainmentMenu ul.AspNet-Menu ul  /* Tier 2 */
   7: {
   8:     width: 6em;
   9:     top: 100%;
  10:     left: 0;
  11:     font-weight:bold;
  12: }
  13:  
  14: .SimpleEntertainmentMenu ul.AspNet-Menu ul ul  /* Tier 3+ */
  15: {
  16:     top: 0%;
  17:     left: 6em;
  18:     font-weight:normal;
  19: }
  20:  
  21: .SimpleEntertainmentMenu li /* all list items */
  22: {
  23:     width: 6em;
  24:     background: #efefef;
  25: }
  26:  
  27: .SimpleEntertainmentMenu li:hover, /* list items being hovered over */
  28: .SimpleEntertainmentMenu li.AspNet-Menu-Hover
  29: {
  30:     background: Black;
  31: }
  32:  
  33: .SimpleEntertainmentMenu a, /* all anchors and spans (nodes with no link) */
  34: .SimpleEntertainmentMenu span
  35: {
  36:     color: Black;
  37:     padding: 4px 2px 4px 8px;
  38:     border:1px solid #cccccc;
  39:     background: transparent url(arrowRight.gif) right center no-repeat;
  40: }
  41:  
  42: .SimpleEntertainmentMenu li.AspNet-Menu-Leaf a, /* leaves */
  43: .SimpleEntertainmentMenu li.AspNet-Menu-Leaf span
  44: {
  45:     background-image: none !important;
  46: }
  47:  
  48: .SimpleEntertainmentMenu li:hover a, /* hovered text */
  49: .SimpleEntertainmentMenu li:hover span,
  50: .SimpleEntertainmentMenu li.AspNet-Menu-Hover a,
  51: .SimpleEntertainmentMenu li.AspNet-Menu-Hover span,
  52: .SimpleEntertainmentMenu li:hover li:hover a,
  53: .SimpleEntertainmentMenu li:hover li:hover span,
  54: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover a,
  55: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover span,
  56: .SimpleEntertainmentMenu li:hover li:hover li:hover a,
  57: .SimpleEntertainmentMenu li:hover li:hover li:hover span,
  58: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover li.AspNet-Menu-Hover a,
  59: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover li.AspNet-Menu-Hover span
  60: {
  61:     color: White;
  62:     background: transparent url(activeArrowRight.gif) right center no-repeat;
  63: }
  64:  
  65: .SimpleEntertainmentMenu li:hover li a, /* the tier above this one is hovered */
  66: .SimpleEntertainmentMenu li:hover li span,
  67: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li a,
  68: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li span,
  69: .SimpleEntertainmentMenu li:hover li:hover li a,
  70: .SimpleEntertainmentMenu li:hover li:hover li span,
  71: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover li a,
  72: .SimpleEntertainmentMenu li.AspNet-Menu-Hover li.AspNet-Menu-Hover li span
  73: {
  74:     color: Black;
  75:     background: transparent url(arrowRight.gif) right center no-repeat;
  76: }
  77:  
  78: .SimpleEntertainmentMenu .AspNet-Menu-Selected /* this tier is selected */
  79: {
  80:     border: solid 1px #00ff00 !important;
  81: }
  82:  
  83: .SimpleEntertainmentMenu .AspNet-Menu-ChildSelected /* a tier below this one is selected */
  84: {
  85:     border: solid 1px #ff0000 !important;
  86: }
  87:  
  88: .SimpleEntertainmentMenu .AspNet-Menu-ParentSelected /* a tier above this one is selected */
  89: {
  90:     border: solid 1px #0000ff !important;
  91: }
  92:  
  93: #EntertainmentMessage
  94: {
  95:     padding-top: 2em;
  96:     clear: both;
  97: }

 

Well that is pretty self describing, as I have already mention that the CSS Control adapter will rendered Divs and Unorder lists instead of table for Menu Control. Here we are simply specifying the style for Menu element on different level.

Once you have complete with the creation of CSS file, you need to link this with your page and for that

   1: <link rel="stylesheet" href="/CSS/SimpleMenu.css" type="text/css" />

I have created the CSS File under CSS folder, which can be some thing else in your case.

That is it, it is pretty simple yet effective to use CSS Control Adapter with your asp.net application because it can give standardized HTML as output which is easy to design.
You can download the VS 2008 project file.

Configure SQL Server 2008 for File Stream

Well, from past two days I am working on SQL Server 2008 new feature called File Stream. In the period of SQL Server 2005 when we want to store some files to the database we can have that using varbinary(max) but that approach is not either smart nor popular amongst the developers. So, many developers like me wants to store images on any physical location and keep the file location in the table. But, that have issues too, what if somebody delete the files from physical location ? will  file entries in the database also deleted and what if somebody deleted the records using t/sql will the files on the physical location also deleted.

In nutshell, both the previous approaches have issues. So, this File Stream data type can replace the problem we had before. It will save the file to the physical location and store the stream of of that file to the table. In my opinion, that is the smart approach.

So, let us dig down and see how can we configure file stream to the new SQL Server 2008 instance , Database and then Table.

Getting Your SQL Server 2008 Instance Ready for File Stream:
  • Goto Start > Programs > Sql Server 2008 > Configuration Tools > SQL Server Configuration Manager
  • Now that Configuration Manager is open, right click on the default instance and go to properties.
  • On this form, Go to File Stream Tab and Enable the file stream. See the image below

sc_filestream

Ok, let me brief you the option we have here.

  • Enable FileStream for transact-sql access : This way you can access the file using t/sql
  • Enable FileStream for File I/O streaming access : By checking this you can access the files using IO Stream
  • All remote clients to have streaming access to file stream data : Here you are allowing remote connections to play around with File Stream Files.

Once you finish with this you need to set the access level by run the following query. Please bear in mind that the following query will not work until you set FileStream stuff from Configuration manager.

   1: EXEC sp_configure filestream_access_level, 2 -- 0 : Disable , 1 : Transact Sql Access , 2 : Win IO Access
   2: GO
   3: RECONFIGURE
   4: GO

Or alternatively, you can

  • Go to SQL Server Management Studio
  • Right Click the database server then properties
  • From the properties window select advance and you will see the following screen

sc_filestream2

  •  Now simply select the access level you want for your server.
Enable database to have FileStream Data type:

Now, you have done with the sql server instance configuration. Let’s move to Database Configuration. How can we create a database which is FileStream Supported.

For that there are two options.

  1. Using T-sql
  2. Using Management Studio

Using T-Sql

For that you need to run the following query

   1: CREATE DATABASE Learning_Db 
   2: ON
   3: PRIMARY ( NAME = LearnDb1,
   4:     FILENAME = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL10.SQLEXPRESS\\MSSQL\\DATA\\Learning_Db .mdf'),
   5: FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM( NAME = LearnDb2,
   6:     FILENAME = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL10.SQLEXPRESS\\MSSQL\\DATA\\Learning_DbStream')
   7: LOG ON  ( NAME = LearnDbLog1,
   8:     FILENAME = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL10.SQLEXPRESS\\MSSQL\\DATA\\Learning_Db.ldf')
   9: GO

Ok now, notice that along with the Primary and Log file we have one new file group which we use for FileStream. Remember we have discuss above that FileStream will save a file on a physical location and store the stream in the the database which will later use for accessing that file. 

Now, when you go to the location where we create our new database you will see there is a folder (in our case it should be “Learning_DbStream”).  This folder contain all the files of your FileStream.

Using Management Studio

While creating a new database window go to file group, you will find the File Stream section at the bottom. See image below
Note : If your database is already created, you can set FileStream stuff by right click your database and then properties and then file group

sc_filestream3

For using the FileStream, you need to add a File Stream Group here and make it default. Once you add that, Go to the Files and add a new file

  • Give Logical name In our case we have used “LearningDb_FileStream” and then Select  “FileStream Data” from file type.
  • After that, you only need to set the path and that’s it

    sc_filestream4
  • Click Ok, and now your database is ready to play with FileStream. 
Using FileStream Data type in table:

Now, for using the FileStream data type in table you need to create a Unique Column which is off uniqueidentified datatype and a column that uses varbinary(max) to store the Stream. Here is the SQL for that

   1: CREATE TABLE [dbo].[tbl_Files](
   2:     [Id] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE,
   3:     [SystemNumber] [int] NOT NULL,
   4:     [SystemFile] [varbinary](max) FILESTREAM NULL
   5: ) ON [PRIMARY]
   6:  
   7: GO
Just give this a Go and you are all done with FileStream configuration.