Wednesday, February 28, 2007

Remove extra space from Validation Summary

       Hi, You all have observe that when we use validation summary,  it takes some extra space between header text and error messages.

      You can remove extra space by using style sheet. Below is the code.

<style type="text/css">
    UL
   {
          margin: 0 ;
          padding:5px;
   }
</style>

Fig - (1) CSS to remove extra space.

Happy Programming.

Monday, February 26, 2007

Google Map API control for ASP.NET

              I have to work with google map in my current project. I search on net for the documentation of the API. Google has given really good exaples how to use that. However, everything is done using javascript. I was searching for the control that allow me to do all this at code behind. I found really good control at

             http://be.sys-con.com/read/171162_1.htm

          I have modified it according to my requirement.  If you have any question you can ask me.

Happy Programming.

Thursday, February 22, 2007

Use XML as input parameter to SP

         Few days ago, in my blog(http://chiragrdarji.wordpress.com/2007/02/19/split-function-in-sql/)  I mentioned how to pass and use multiple values in single parameter in SP. I have mentioned that you can use XML format to do the same. Let me show you how to do that.

         Cionsider that you have to delete 5 rows from table and you have value of primary key for those 5 records. You have to prepare the XML document for these 5 IDs and pass it as a parameter to SP. Below is the functiion that generates XML.

       I have passed 5 IDs as coma seperated string in "Value", and NodeName as parameters. I will Explain NodeName later.

public static string GetOpenXMLFormat(string Value,string NodeName)
{
            string strReturnVAlue = string.Empty; 
            // Create Root node.
             strReturnVAlue = "<Root>"

            if (Value.Length > 0)
            {
                  string[] strTemp = Value.Split(new string[] {","}, 
                                                          StringSplitOptions.RemoveEmptyEntries);

                  for (int i = 0; i < strTemp.Length; i++)
                 {
                       strReturnVAlue += "<" + NodeName + "IDS " + NodeName + "ID ='"
                                                                + strTemp[i] + "'/>"

                  }
             }
            strReturnVAlue += "</Root>"
            return strReturnVAlue;
}

Fig - (1) C# code generate XML document.

 

           Lets call above function GetOpenXMLFormat("1,2,3,4,5" , "Emp"). This will generate XML file as shown below.

<Root>
         <EmpIDS EmpID = 1/>
         <EmpIDS EmpID = 2/>
         <EmpIDS EmpID = 3/>
         <EmpIDS EmpID = 4/>
         <EmpIDS EmpID = 5/>
</Root>

Fig - (2) Generated XML strig.

      Consider that we pass this parameter "@EmpIDS" to any SP. Below is the code that shows how to read this parameter in SP.

 

DELARE @EmpID int

DECLARE @docHandle int

EXEC sp_xml_preparedocument @docHandle OUTPUT, "@EmpIDS

SELECT * Into #TempEntities FROM
OPENXML(@docHandle, N'/Root/IDS',1) WITH (EmpID int)

DECLARE TempCursor CURSOR FOR

SELECT SubGroupID, TrainingModuleID FROM #TempEntities

OPEN TempCursor

/* For each row in cursor*/
FETCH NEXT FROM TempCursor INTO @EmpID

/* Loop through cursor for remaining GroupID */
WHILE @@FETCH_STATUS = 0
BEGIN

      // Wirte a code to do desire operation

END

 

Fig - (3) Ream XML string parameter in SP.

         You can pass more than one attribute in XML parameter and read it. Below is the sample for 2 values 

OPENXML(@docHandle, N'/Root/IDS',1) WITH (SubGroupID int '@SubGroupID', TrainingModuleID int '@TrainingModuleID')

Fig - (3)  Read values of 2 parameters

Happy programing.

Monday, February 19, 2007

Split function in SQL

          I was working at home and extending a gridview control with some extra features I required. I have added one column with checkbox for multiple delete. To delete multiple records I need to pass either multiple ID to SP and delete all or can pass each ID one by one to SP.

        I passed all ID as coma separated string to SP.  I used split function to split the coma separated ID, so that I can use those ID in inner query. For example

DELETE FROM TableName WHERE ID IN (SELECT dbo.fun_Split(@AllID, ',' ))

Here you have to pass string value and separator as a parameter. In my case, I have used "," as seperator. Below is the function,

 

Create function fun_Split (@String nvarchar(4000), @Delimiter char(1))
Returns @Results Table (Items nvarchar(4000))
As

Begin
         Declare @Index int
         Declare @Slice nvarchar(4000)
         Select @Index = 1
        If @String Is NULL
                 Return
        While @Index != 0
        Begin
               Select @Index = CharIndex(@Delimiter, @String)
               If (@Index != 0)
                      Select @Slice = left(@String, @Index - 1)
               else
                     Select @Slice = @String

               Insert into @Results(Items) Values (@Slice)
               Select @String = right(@String, Len(@String) - @Index)
               If Len(@String) = 0
                     break
       End
       Return
End

Fig -(1) Split function SQL.

             There is another way to do the same. You can use open XML format to pass more than one parameters to SP. I will explain that in my next blog.

Happy Programing.

Friday, February 16, 2007

Dotnet 3.0 Training Material

        I was serching for good material to learn cotnet 3.0. I found the good link which allows to download PPT file. Below is the link,

        http://www.dotnet-university.com/

Using publisher policy assemblies

            As we all knows .NET support side by side execution of multiple versions of component. In most cases, updating a component is simple.However, even in the .NET world, it is possible to break assembly binding when you update a component.  One achieve that control is the publisher policy assembly.

What is a publisher policy assembly?

                 A publisher policy assembly is an assembly that configures the policy to be used when the .NET runtime binds to an assembly. The publisher policy assembly is installed into the GAC and is named using the following naming convention:

                policy.major_ver.minor_ver.assembly.dll

                    The major_ver and minor_ver refer to the major and minor version of the old version of the assembly. Therefore, if you are updating version 1.0 of Website.dll to version 2.0, and you want all existing applications to bind to the new version, the publisher policy assembly name would be:

                 policy.1.0.website.dll

After this publisher policy assembly is installed into the GAC, any application that references version 1.0 of Website.dll will bind to version 2.0 of Website.dll instead. At this point, you might be asking how the .NET runtime knows to bind to version 2.0 of Website.dll when it sees the publisher policy assembly in the GAC. The answer lies in the publisher policy file, an XML configuration file that is used to create the publisher policy assembly.

                       The publisher policy file contains the information necessary to redirect the binding from one version of an assembly to a new version. After you've created the publisher policy file, you use the .NET Assembly Linker utility (Al.exe) to create the publisher policy assembly.


                        Here is an example of a publisher policy file that redirects any reference to version 1.0 of Website.dll to version 2.0. The public key token can be obtained by looking at the properties of the assembly currently installed in the GAC.

<configuration>
<runtime>
 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">      <dependentAssembly>
<assemblyIdentity name="website" publicKeyToken="18517ea673f8584b" culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/> </dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

 

The entire process

Scenario: You want to ensure that any ASP.NET application currently referencing version 1.0 of your server control uses version 2.0 instead after the updated version is installed. You don't want anyone to have to modify configuration files for this to happen. You have wisely determined that a publisher policy assembly is the way to go.
This is how you should proceed.

1. Change the version and recompile.    The first step is to create the new version of your component. After you've done that, you will need to modify the version number in the AssemblyInfo file for your component.

2.Create the publisher policy file.Create the publisher policy file for the assembly using the format shown above.

3.Use Assembly Linker (Al.exe) to create the publisher policy assembly. The Assembly Linker is included with the .NET Framework SDK. To create the publisher policy assembly that redirects a binding from version 1.0 of Website.dll to version 2.0 using a publisher policy file called website.config, run the following command:

al /link:website.config /out:policy.1.0.website.dll /keyfile:c:\keyfile.snk

This command will create a new assembly called policy.1.0.website.dll. This naming convention is important, as indicated in the "What Is a Publisher Policy Assembly?" section.

4.Install the publisher policy assembly into the Global Assembly Cache. The publisher policy assembly is installed into the GAC. It will be used by the .NET runtime when any application attempts to bind to version 1.0 of the Website.dll, and it will force the application to bind to the new version automatically.

5.Install the new version into the Global Assembly Cache. Install the new version of the component into the GAC. After the new version has been installed, the old version can be safely removed.

6.Restart Microsoft Internet Information Services (IIS). The final step is to restart IIS. This is necessary because of the way the .NET runtime binds to an assembly. If the .NET runtime has already bound to a specific assembly, it will reuse that binding. Therefore, for the binding redirect to the new assembly to work, you must restart the worker process.

                  After completing these steps, any application that was built with a reference to version 1.0 of Website.dll will automatically use version 2.0. Publisher policy assemblies offer a convenient way to ensure that developers have full control over assembly binding. As you've seen in this article, if your goal is to force existing applications to use a new version of your component, a publisher policy assembly provides you with the confidence that applications will always use the version you expect them to use without having to alter any configuration files or rely on manual changes by a server administrator.

 

You can find detail information at,

http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B891030

Happy Programming.

Thursday, February 15, 2007

Swap values of three variables without using fourth variable

       In my recent interview, a well known company in ahmedabad having branches in all over India, I was asked to write a programm. I have to swap the values of three variables without using fourth varable.  I found it really triky. I will first explain this with two variables and than show for three variables in two diffrent ways.

                 Lets, consider the case    a = 10 and b=20. I have to write the programm so that result will be a= 20 and b= 10. Below is the steps,

a = 10;
b=20;
a = a+b; ( a= 30)
b = a - b; (b = 30 - 20 =10)
a =  a-b; (a = 30-10 = 20)

Fig - 1 Steps to swap the values of two variables.

     Now take three variables, a= 10, b=20 and c =30. The output should be a=30, b=10 and c= 20. First way to achive this is you can use steps mentioned in Fig -1 three times. First swap a and b than a and c. Below is the steps,

 

a = 10;
b=20;
c=30;


a = a+b; ( a= 30)
b = a - b; (b = 30 - 20 =10)
a =  a-b; (a = 30-10 = 20)

// Here a= 20 and b= 10;

a = a+c; ( a= 20 + 30 = 50)
c = a - c; (c = 50 - 30 =20)
a =  a-c; (a = 50-20 = 30)

// Here a= 30 and c= 20;

Fig - 2 Steps to swap the values of three variables.

 

Second way of swapping the values of three variable is,

a = 10;
b=20;
c=30;


a = a+b+c;  ( a= 60)
b = a - (b+c);  (b = 60 - (20+30) =10)
c =  a- (b+c);  (c = 60 - (10 + 30) = 20)
a = a- (b+c);   (a = 60 - (10 + 20) = 30)

Fig - 3 Steps to swap the values of three variables.

Happy Programing.

Tuesday, February 13, 2007

Send an Email using SQL Server

         In my recent project, we have  to send an email to client when his/her subscription is about to complete. For this we need to check the database daily at and have to send an email to related client regarding their subscription end date. The simplest idea is to create the job for this task, which daily sends an email to client. The main thing is a SP which sends an email. We search on Google and found one. My friend modified it according to our requirement. I had written proper comments for each line so that any one can understand and modify it.

        SP takes From Address, To Address, CC, Subject and Body as parameter. It creates CDO object and use it to send an email. Your IIS must have SMTP server and it must be properly configured to send an email. I have also included some links from MSDN which can helps to configure SMTP server. Below is the SP,

 

--------------IIS server must be configured to send an email------------------------------
CREATE PROCEDURE usp_SnapSendMail @From varchar(2000) , @To varchar(2000), @CC varchar(2000) , @Subject varchar(1000)=" ", @Body varchar(7000) =" "

/******************************************

This stored procedure takes the parameters and sends an e-mail.
All the mail configurations are hard-coded in the stored procedure.
Comments are added to the stored procedure where necessary.
References to the CDOSYS objects are at the following
MSDN Web site: http://msdn.microsoft.com/library/default.asp?url=/ library/en-us/cdosys/html/_cdosys_messaging.asp

*******************************************/

AS
Declare @iMsg int
Declare @hr int
Declare @source varchar(255)
Declare @description varchar(500)
Declare @output varchar(1000)

--***** Create the CDO.Message Object *****

EXEC @hr = sp_OACreate 'CDO.Message', @iMsg OUT

--*****Configuring the Message Object *****

-- This is to configure a remote SMTP server.
-- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_schema_configuration_sendusing.asp
EXEC @hr = sp_OASetProperty @iMsg, 'Configuration.fields ("http://schemas.microsoft.com/cdo/configuration/sendusing").Value','2'

-- This is to configure the Server Name or IP address.

-- Replace MailServerName by the name or IP of your SMTP Server.
EXEC @hr = sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/smtpserver").Value', 'dotnet-dipak'

EXEC @hr = sp_OASetProperty @iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/sendemailaddress ").Value','dotnet-dipak'

-- Save the configurations to the message object.
EXEC @hr = sp_OAMethod @iMsg, 'Configuration.Fields.Update', null

-- Set the e-mail parameters.
EXEC @hr = sp_OASetProperty @iMsg, 'To', @To
EXEC @hr = sp_OASetProperty @iMsg, 'From', @From
EXEC @hr = sp_OASetProperty @iMsg, 'CC', @CC
EXEC @hr = sp_OASetProperty @iMsg, 'Subject', @Subject

-- If you are using HTML e-mail, use 'HTMLBody' instead of 'TextBody'.
EXEC @hr = sp_OASetProperty @iMsg, 'HTMLBody', @Body
EXEC @hr = sp_OAMethod @iMsg, 'Send', NULL

-- Sample error handling.

IF @hr <>0 select @hr BEGIN EXEC @hr = sp_OAGetErrorInfo NULL, @source OUT, @description OUT IF @hr = 0 BEGIN SELECT @output = ' Source: ' + @source PRINT @output SELECT @output = ' Description: ' + @description PRINT @output END ELSE BEGIN PRINT ' sp_OAGetErrorInfo failed.' RETURN END END
-- Do some error handling after each step if you have to.
-- Clean up the objects created.
EXEC @hr = sp_OADestroy @iMsg

GO

Fig -1 SP to send an Email

 

Happy Programing.

Monday, February 12, 2007

Gridview with Radio Buttons

      In my current project, I have to display a grid which has Radio button in each row and user can select one radio button. The task was simple, according tome. I took Template Field and place radio button in item template. I set "GropName"  property to "Commom".  According to me its enough and now user can select only one radio button. However the result was unexpected and I found that user can select more than one !!!!!!. Then I came to know that, GroupName property works only when all radio buttons are in same row. Then I took HTML Control for radio button and set "Name" property. This time, the grid and radio buttons work perfectly.

    As now, Radio buttons are HTML controls, I am not able to get it on server side. When user select any radio button and press submit, Control will not available at code behind, you can use "e.Item.FindControl" as it is not "runat='server'". I want ID "Primary Key" value for selected radio button. To achive this I took the help of Javascript. I wrote javascript function that sets the values of "Primary Key" in hidden field when user clicks on any radio button. Now when user clicks on Submit button, user can get selected value froim hidden field.

 

<asp:Repeater ID="rptJobPsting" runat="server" OnItemDataBound="rptJobPsting_ItemDataBound">
<ItemTemplate>
     <table>
           <tr>
               <td valign="top">
                        <input type="radio" id="JobPosting" onclick="CheckISRMSSelectd(this.id,this.checked,'<%#Eval("PackageAmount")%>');"
name="JobPosting" value="<%#Eval("PackageID")%>" />
            </td>
         </tr>
       </table>
</ItemTemplate>
</asp:Repeater>

Fig. - 1 Repeater Control with HTML Radio Button.

 

function CheckISRMSSelectd(ControlID,Value,Amount)
{
document.getElementById(HiddenFieldName).value = Amount + " Rs";
}

Fig. - 2 Javascript functions to check selected

 

Happy Programming.

Print the page using Javascript

          Printing the page using javascript is very common functionality that every web developer requires. Every one has implemented that, though I would like to write a blog for this. My requirement is that, I have to hide few controls like buttons, drop downlist etc. before printing the page. To implemet this, I had set the display properties of those controls to "none" before printing and then again reset it. Below is the scrpt for that,

function PrintPage(Control)
{

// Pass the controls ID, which you do not want to print and
// its display property to "none"
Control.style.display = "none"
var PrintValue = document.getElementById('dvPrint').innerHTML;
var WinPrint = window.open('','','left=' + screen.width + ',top=' + screen.height + ',width=1,height=1,toolbar=0,scrollbars=0,status=0');
WinPrint.document.write(PrintValue);
WinPrint.document.close();
WinPrint.focus();
WinPrint.print();
WinPrint.close();
// Set display property to ""
Control.style.display = "";
return false;
}

Monday, February 05, 2007

Select Distinct form Datatable

 

I need to write a code by which I can show distinct product name in drop down list and I have to do that from code once I have received dataset from DAL. I can iterate through all records and sore the distinct values in Array. I thought some other way for this. My function will take datatable as argument and returns new datatable with only one colun on which yu want distinct records. You may change it and return all the columns just by changing few lines. Below is the function,

 

private DataTable SelectDistinct(string ReturnTableName, DataTable SourceTable, string ReturnFieldName, string AdditionalFilterExpression)
{
DataTable dt = new DataTable(ReturnTableName);
dt.Columns.Add(ReturnFieldName, SourceTable.Columns[ReturnFieldName].DataType);
object LastValue = null;
foreach (DataRow dr in SourceTable.Select("", ReturnFieldName + " Asc"))
{
if (LastValue == null || !(ColumnEqual(LastValue, dr[ReturnFieldName])))
{
LastValue = dr[ReturnFieldName];
dt.Rows.Add(new object[] { LastValue });
}
}

return dt;
}

//Following function compares the value of two objects and returns true or false based on the same.
private bool ColumnEqual(object A, object B)
{
// Compares two values to see if they are equal. Also compares DBNULL.Value.
// Note: If your DataTable contains object fields, then you must extend this
// function to handle them in a meaningful way if you intend to group on them.

if (A == DBNull.Value && B == DBNull.Value) // both are DBNull.Value
return true;
if (A == DBNull.Value || B == DBNull.Value) // only one is DBNull.Value
return false;
return (A.Equals(B)); // value type standard comparison
}

Happy Programing.

Thursday, February 01, 2007

Converting DataSet into Recordset

         

           I was working on one of my most challenging application, before few months. In that we have to use third party DLL for generating PDF file in ASP.NET 2.0. The requirement is that we have to use the DLL which client was using for his ASP application. The main hurdle  for me is that, the DLL accepts only Recordset as input.

           I search on the net however I did not found any solution. After few days of searching I tried to implement by my own. I took the help of my senior "Nikhil" and we foung the solution. Below is the code for converting DataSet into Recordset.

 

static public ADODB.Recordset ConvertToRecordset(DataTable inTable)
{
     ADODB.Recordset result = new ADODB.Recordset();
     result.CursorLocation = ADODB.CursorLocationEnum.adUseClient;

     ADODB.Fields resultFields = result.Fields;
     System.Data.DataColumnCollection inColumns = inTable.Columns;

    foreach (DataColumn inColumn in inColumns)
    {
          resultFields.Append(inColumn.ColumnName
         , TranslateType(inColumn.DataType)
         , inColumn.MaxLength
         , inColumn.AllowDBNull ? ADODB.FieldAttributeEnum.adFldIsNullable :
         ADODB.FieldAttributeEnum.adFldUnspecified
        , null);
    }

    result.Open(System.Reflection.Missing.Value
   , System.Reflection.Missing.Value
   , ADODB.CursorTypeEnum.adOpenStatic
   , ADODB.LockTypeEnum.adLockOptimistic, 0);

   foreach (DataRow dr in inTable.Rows)
   {
              result.AddNew(System.Reflection.Missing.Value,
              System.Reflection.Missing.Value);

              for (int columnIndex = 0; columnIndex < inColumns.Count; columnIndex++)
             {
                     resultFields[columnIndex].Value = dr[columnIndex];
              }
     }

     return result;
}

static ADODB.DataTypeEnum TranslateType(Type columnType)
{
         switch (columnType.UnderlyingSystemType.ToString())
        {
                    case "System.Boolean":
                               return ADODB.DataTypeEnum.adBoolean;

                    case "System.Byte":
                              return ADODB.DataTypeEnum.adUnsignedTinyInt;

                   case "System.Char":
                              return ADODB.DataTypeEnum.adChar;

                   case "System.DateTime":
                              return ADODB.DataTypeEnum.adDate;

                   case "System.Decimal":
                              return ADODB.DataTypeEnum.adCurrency;

                   case "System.Double":
                             return ADODB.DataTypeEnum.adDouble;

                   case "System.Int16":
                              return ADODB.DataTypeEnum.adSmallInt;

                   case "System.Int32":
                             return ADODB.DataTypeEnum.adInteger;

                    case "System.Int64":
                              return ADODB.DataTypeEnum.adBigInt;

                   case "System.SByte":
                             return ADODB.DataTypeEnum.adTinyInt;

                   case "System.Single":
                            return ADODB.DataTypeEnum.adSingle;

                   case "System.UInt16":
                             return ADODB.DataTypeEnum.adUnsignedSmallInt;

                    case "System.UInt32":
                              return ADODB.DataTypeEnum.adUnsignedInt;

                   case "System.UInt64":
                             return ADODB.DataTypeEnum.adUnsignedBigInt;

                    case "System.String":
                   default:
                             return ADODB.DataTypeEnum.adVarChar;
         }
}

 

You can email me, if you have any questions.

Happy Programming.

Read value from Registry

 

                Before few months when I was ne in Cygnet, I was assign a task to read store connection string in registry and read the value from there whenever require. This is something new and I had never implemented it before.

                  Thanks to my collegue (now friend ) SEHUL a little master, who helped me in doing this. Below is the code.

Microsoft.Win32.RegistryKey rgk = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, "MachineName");

rgk = rgk.OpenSubKey(@"HARDWARE\DESCRIPTION\SYSTEM\CentralProcessor\0");
string strValue =Convert.ToString( rgk.GetValue("Identifier"));
MessageBox.Show(strValue);

Happy programming.