Friday, December 4, 2015

Creating Data Reader Extensions in C# for Nullable values

When we use data readers in our data access layers of a c# application that could be a part of web or windows, we have to handle nullable parameters and nullable values before casting or accessing to avoid any run time errors or basically to avoid crashing the application. So we can write additional reader extension to use that can handle null values for a nullable property. For example see the below method.

 public static class DataReaderExtensions  
   {  
     public static string GetStringNullable(this IDataReader reader, int ordinal)  
     {  
       return reader.IsDBNull(ordinal) ? null : reader.GetString(ordinal);  
     }  
     public static int? GetInt32Nullable(this IDataReader reader, int ordinal)  
     {  
       return reader.IsDBNull(ordinal) ? (int?)null : reader.GetInt32(ordinal);  
     }  
     public static DateTime? GetDateTimeNullable(this IDataReader reader, int ordinal)  
     {  
       return reader.IsDBNull(ordinal) ? (DateTime?)null : reader.GetDateTime(ordinal);  
     }  
     public static decimal? GetDecimalNullable(this IDataReader reader, int ordinal)  
     {  
       return reader.IsDBNull(ordinal) ? (decimal?)null : reader.GetDecimal(ordinal);  
     }  
     public static bool? GetBooleanNullable(this IDataReader reader, int ordinal)  
     {  
       return reader.IsDBNull(ordinal) ? (bool?)null : reader.GetBoolean(ordinal);  
     }  
     public static byte? GetByteNullable(this IDataReader reader, int ordinal)  
     {  
       return reader.IsDBNull(ordinal) ? (byte?)null : reader.GetByte(ordinal);  
     }  
     public static double? GetDoubleNullable(this IDataReader reader, int ordinal)  
     {  
       return reader.IsDBNull(ordinal) ? (double?)null : reader.GetDouble(ordinal);  
     }  
   }  

Many data types are covered with this method and this could be copied to your base class of data access layer which then be accessible as a static method to any data layer methods. Look at the below example.

 while (reader.Read())  
           {  
             AdmActionEntity action = new AdmActionEntity();  
             action.idActionType = action.ActionType.idActionType = reader.GetInt32(idActionTypeOrdinal);  
             action.ActionType.lbActionType = reader.GetStringNullable(lbActionTypeOrdinal);  
             action.nbToBeAssigned = reader.GetInt32(nbToBeAssignedOrdinal);  
             action.bnToBeDone = reader.GetInt32(bnToBeDoneOrdinal);  
             ActionList.Add(action);  
           }  

This is a peace of code of a data access method that the reader is a SqlDataReader and the string value of lbActionType can also be nullable. So directly using GetString may throw null reference if you don't handle it in reader object. So the "GetStringNullable" will save lot of your time and additional coding.

Get this code and try it yourself. It is easy as say cheese. :)\

Remember the saying,

“I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it.” ― Bill Gates

It is not being lazy sometimes, it is the way of finding alternatives. :)




Encryption and Decryption (Cryptography) in C#

Application level encryption and decryption is needed for certain cases when security is applied. It can simply be user credentials or even may be user specific data. Anyway, it is a good way or using a unique encryption and decryption method across the application.

Cryptography is widely used by almost all the developers and it is not that hard to have a common EncryptionUtility for your own application. Look at the sample class below;

 public class EncryptionUtility  
   {  
     static readonly string PasswordHash = "Z!R3cVwPa_b7^5TZ!_rE";  
     static readonly string SaltKey = "&7fHXcc2^$8x@AwrdC$c";  
     static readonly string VIKey = "6=ZvwA##4Ms3*yV2D&6$";  
     //Encryption method  
     public static string Encrypt(string plainText)  
     {  
       try  
       {  
         byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);  
         byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);  
         var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };  
         var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));  
         byte[] cipherTextBytes;  
         using (var memoryStream = new MemoryStream())  
         {  
           using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))  
           {  
             cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);  
             cryptoStream.FlushFinalBlock();  
             cipherTextBytes = memoryStream.ToArray();  
             cryptoStream.Close();  
           }  
           memoryStream.Close();  
         }  
         return Convert.ToBase64String(cipherTextBytes);  
       }  
       catch (Exception)  
       {  
         //You can use your own error handling method. In this case, the text is returned.  
         return plainText;  
       }  
     }  
     //Decryption method  
     public static string Decrypt(string encryptedText)  
     {  
       try  
       {  
         byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);  
         byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);  
         var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };  
         var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));  
         var memoryStream = new MemoryStream(cipherTextBytes);  
         var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);  
         byte[] plainTextBytes = new byte[cipherTextBytes.Length];  
         int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);  
         memoryStream.Close();  
         cryptoStream.Close();  
         return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());  
       }  
       catch (Exception)  
       {  
         return encryptedText;  
       }  
     }  
     //Method to see a given text is encrypted or not.  
     public static bool IsEncrypted(string text)  
     {  
       if (text.Equals(Decrypt(text)))  
         return false;  
       else  
         return true;  
     }  
   }  

Because the methods are defined as static, you can use it as below;

 EncryptionUtility.Encrypt(username)  

Copy this code and try once. :)

Thursday, December 3, 2015

MsSQL - Getting current week number

To calculate the week number, there is no straight function in MsSQL and we need to do some calculation. And here is how it can be taken easily

 select (DATEPART(dy,DATEDIFF(dd,0,getdate())/7*7+3)+6)/7 as 'WeekNumber'   

And the result is;


Thanks for reading... :)

Email Helper in C# - A Common & Easy Way of Sending Emails

Most of the time, it is common to send emails through the application which some may related to technical or error handling and sometimes to customers which could be even internal or external. Such cases, SmtpClient is the class we use in ASP.Net

Using a bit of OOP can help to have a common way of sending emails and can be widely used across the application. Below is an example of an Email helper class which can be used widely. 

 public class EmailHelper  
   {  
     private MailMessage Message = null;  
     private SmtpClient smtpClient = null;  
     public MailAddress FromAddress { get; set; }  
     public string Subject { get; set; }  
     public string Body { get; set; }  
     public EmailHelper()  
     {  
       smtpClient = new SmtpClient();  
       smtpClient.Host = ConfigurationManager.AppSettings["smtpHost"];  //Configure as your email provider
       smtpClient.UseDefaultCredentials = false;  
       //smtpClient.EnableSsl = true;//comment if you don't need SSL  
       smtpClient.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["userName"], ConfigurationManager.AppSettings["password"]);  
       smtpClient.Port = Convert.ToInt32(ConfigurationManager.AppSettings["port"]);  
       Message = new MailMessage();  
     }  
     public EmailHelper(string host, int port, string userName, string password, bool ssl)  
       : this()  
     {  
       smtpClient.Host = host;  
       smtpClient.Port = port;  
       smtpClient.EnableSsl = ssl;  
       smtpClient.Credentials = new NetworkCredential(userName, password);  
     }  
     public void AddToAddress(string email, string name = null)  
     {  
       if (!string.IsNullOrEmpty(email))  
       {  
         email = email.Replace(",", ";");  
         string[] emailList = email.Split(';');  
         for (int i = 0; i < emailList.Length; i++)  
         {  
           if (!string.IsNullOrEmpty(emailList[i]))  
             Message.To.Add(new MailAddress(emailList[i], name));  
         }  
       }  
     }  
     public void AddCcAddress(string email, string name = null)  
     {  
       if (!string.IsNullOrEmpty(email))  
       {  
         email = email.Replace(",", ";");  
         string[] emailList = email.Split(';');  
         for (int i = 0; i < emailList.Length; i++)  
         {  
           if (!string.IsNullOrEmpty(emailList[i]))  
             Message.CC.Add(new MailAddress(emailList[i], name));  
         }  
       }  
     }  
     public void AddBccAddress(string email, string name = null)  
     {  
       if (!string.IsNullOrEmpty(email))  
       {  
         email = email.Replace(",", ";");  
         string[] emailList = email.Split(';');  
         for (int i = 0; i < emailList.Length; i++)  
         {  
           if (!string.IsNullOrEmpty(emailList[i]))  
             Message.Bcc.Add(new MailAddress(emailList[i], name));  
         }  
       }  
     }  
     public void AddAttachment(string file, string mimeType)  
     {  
       Attachment attachment = new Attachment(file, mimeType);  
       Message.Attachments.Add(attachment);  
     }  
     public void AddAttachment(Attachment objAttachment)  
     {  
       Message.Attachments.Add(objAttachment);  
     }  
     public void SendMail()  
     {  
       if (FromAddress == null || (FromAddress != null && FromAddress.Address.Equals("")))  
       {  
         throw new Exception("From address not defined");  
       }  
       else  
       {  
         if (string.IsNullOrEmpty(FromAddress.DisplayName))  
           FromAddress = new MailAddress(FromAddress.Address, string.Empty);  
         Message.From = FromAddress;  
       }  
       if (Message.To.Count <= 0)  
       { throw new Exception("To address not defined"); }  
       Message.Subject = Subject;  
       Message.IsBodyHtml = true;  
       Message.Body = Body;  
       smtpClient.Send(Message);  
     }  
     public static string GetFileMimeType(string fileName)  
     {  
       string fileExt = Path.GetExtension(fileName.ToLower());  
       string mimeType = string.Empty;  
       switch (fileExt)  
       {  
         case ".htm":  
         case ".html":  
           mimeType = "text/html";  
           break;  
         case ".xml":  
           mimeType = "text/xml";  
           break;  
         case ".jpg":  
         case ".jpeg":  
           mimeType = "image/jpeg";  
           break;  
         case ".gif":  
           mimeType = "image/gif";  
           break;  
         case ".png":  
           mimeType = "image/png";  
           break;  
         case ".bmp":  
           mimeType = "image/bmp";  
           break;  
         case ".pdf":  
           mimeType = "application/pdf";  
           break;  
         case ".doc":  
           mimeType = "application/msword";  
           break;  
         case ".docx":  
           mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";  
           break;  
         case ".xls":  
           mimeType = "application/x-msexcel";  
           break;  
         case ".xlsx":  
           mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";  
           break;  
         case ".csv":  
           mimeType = "application/csv";  
           break;  
         case ".ppt":  
           mimeType = "application/vnd.ms-powerpoint";  
           break;  
         case ".pptx":  
           mimeType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";  
           break;  
         case ".rar":  
           mimeType = "application/x-rar-compressed";  
           break;  
         case ".zip":  
           mimeType = "application/x-zip-compressed";  
           break;  
         default:  
           mimeType = "text/plain";  
           break;  
       }  
       return mimeType;  
     }  
   }  
 }  

This class can be used as follows,

 StringBuilder fileNames = new StringBuilder();  
 string strPath = string.Empty;  
 string coType = IPODMT.common.IQuestConst.MessageStatus.Sent;  
 string url = string.Empty;  
 EmailHelper emailHelper = new EmailHelper();  
 emailHelper.FromAddress = new System.Net.Mail.MailAddress(hdnFromAddress.Value.Trim());  
 emailHelper.AddToAddress(txtEmailTo.Text.Trim());  
 emailHelper.AddCcAddress(txtEmailCc.Text.Trim());  
 emailHelper.AddBccAddress(txtEmailBcc.Text.Trim());  
 Dictionary<int, KeyValuePair<string, string>> fileList = null;  
 //Attaching files. Here I keep the values in a session
 fileList = (Dictionary<int, KeyValuePair<string, string>>)Session["UploadedFileList"];  
 foreach (var item in fileList)  
 {  
     emailHelper.AddAttachment(item.Value.Key + item.Value.Value, EmailHelper.GetFileMimeType(item.Value.Value));  
     FileInfo file = new FileInfo(item.Value.Key + item.Value.Value);  
     fileNames.Append(item.Value.Value + "|" + file.Length.ToString() + ";");  
 }  
 string strAttachment = hdnAttachmentTemplate.Value;  
 string msgBody = string.Empty;  
 try  
 {  
     emailHelper.Subject = txtEmailSubject.Text.Trim();  
     if (!string.IsNullOrEmpty(strAttachment) && fileList != null && fileList.Count > 0)  
     {  
         strAttachment = strAttachment.Replace("[flAttachment]", fileList.Count.ToString());  
         msgBody = txtEmailBody.InnerText.Trim() + "<br/>" + strAttachment;  
     }  
     else  
         msgBody = txtEmailBody.InnerText.Trim();// +"<br/>" + txtCustomerInfo.Text.Trim();  
 msgBody = msgBody.Replace("[lbCustomerInfo]", txtCustomerInfo.Text.Trim());  
 emailHelper.Body = msgBody;  
 emailHelper.SendMail();  //After sending email you can clear the session "UploadedFileList"
 }  
 catch (Exception)  
     {  
         //Handle your errors. May be a server log file? Its up to you!
     }  

Copy this code and paste it in your project. Remember to apply the correct SMTPClient settings as per your email provider.

Happy coding.. :)

Wednesday, December 2, 2015

FormsAuthentication in ASP.Net

First, you can read and find rich set of contents here. And going further, it is not that complex to implement and use FormsAuthentication in ASP.Net. For instance, look at the below login method which the FormsAuthentication is used if the user clicked on the "Remember Me" function.

 public void RememberAuthentication(ContextUtility context,string username)  
     {  
       Response.Cookies.Clear();  
       FormsAuthentication.Initialize();  
       FormsAuthentication.SetAuthCookie(EncryptionUtility.Encrypt(username), false);  
       FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(  
         1,                                     // ticket version  
         EncryptionUtility.Encrypt(username),                    // authenticated username  
         DateTime.Now,                                // issued date  
         DateTime.Now.AddDays(7),                          // expiry date  
         true,                                    // true to persist across browser sessions  
         EncryptionUtility.Encrypt(context.GetValueAsInt("idPerson").ToString()),  // can be used to store additional user data  
         FormsAuthentication.FormsCookiePath);                    // the path for the cookie  
       // Encrypt the ticket using the machine key  
       string encryptedTicket = FormsAuthentication.Encrypt(ticket);  
       // Add the cookie to the request to save it  
       HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);  
       cookie.HttpOnly = true;  
       Response.Cookies.Add(cookie);        
     }  

The context is an object containing user details such as usernam, id and many more. The encryption utility is a global method that is used to encrypt any given string. We will discuss the method in detail in the next post.

Lets see how the above "RememberAuthentication" method can be used in login implementation.

 private void Login()  
     {  
       ContextUtility context = new AdmLoginBLL().Login(txtUsername.Text.Trim(), txtPassword.Text.Trim(), ContextEntity);  
       if (cbRememberMe.Checked)  
         RememberAuthentication(context, txtUsername.Text.Trim());  
       if (context.GetValueAsInt("idPerson") > 0)  
         Response.Redirect("Home.aspx", false);  
     }  

The remember me option will make the user to be remembered if he comes back to the site after logged in. To do so, we need to validate the users identity at the page load event.

 if (Context.User.Identity.IsAuthenticated)  
         {  
           Response.Redirect("Home.aspx");  
         }  

Remember to validate Home page with the user logged in and you need to provide authorization as well.





Convert C# DateTime type to JavaScript Date property

When a web method or service serialize an object and pass it to client side with DateTime properties, We need to cast the C# DateTime to JavaScript Date format so that we can treat it as a valid date property. The below method can be used to cast the c# datetime property in to javascript date property.

1. The entity class

 public class icqQuestResourcePrior  
 {  
   public int idQuestPrior { get; set; }  
   public int idResource { get; set; }  
   public int sqOrder { get; set; }  
   public bool flDevFinish { get; set; }  
   public int idQuest { get; set; }  
   public DateTime dtBegin { get; set; }  
   public DateTime? dtEnd { get; set; }  
   public string lbQuest { get; set; }  
   public string lbPersonInitials { get; set; }  
   public int nvWeekNumber { get; set; }  
   public string coType { get; set; }  
   public string coLifeCycle { get; set; }  
   public string lbLateColor { get; set; }  
   public string lbPersonName { get; set; }  
   public int idPerson { get; set; }  
 }  

2. Web Method

 [WebMethod]  
   public string icqQuestResourcePriorGet(int idQuest, int? idPerson, int? idResource, int? idQuestPrior)  
   {  
     return new JavaScriptSerializer().Serialize(new icqHome().icqQuestResourcePriorGet(idQuest, idPerson == 0 ? (int?)null : idPerson, idResource == 0 ? (int?)null : idResource, idQuestPrior == 0 ? (int?)null : idQuestPrior));  
   }  

3. JQuery AJAX Call

 function LoadWRDetails() {  
   var objPara = {  
     idQuest: $("#hdnWRIdQuest").val(),  
     idPerson: 0,  
     idResource: 0,  
     idQuestPrior: 0  
   };  
   $.ajax({  
     type: "POST",  
     url: $('#hdnUrlPrefix').val() + "IPODCommonWS.asmx/icqQuestResourcePriorGet",  
     data: JSON.stringify(objPara),  
     contentType: "application/json; charset=utf-8",  
     dataType: "json",  
     success: function (msg) {  
       var ret = JSON.parse(msg.d);  

       var re = /-?\d+/;  
       var StartDate = re.exec(ret.dtBegin); // returns "/Date(1245398693390)/";   
       var txtWRStartDate = new Date(parseInt(StartDate[0]));  
       var EndDate = re.exec(ret.dtEnd); // returns "/Date(1245398693390)/";   
       var txtWREndDate = new Date(parseInt(EndDate[0]));  

       var dtBegin = (txtWRStartDate.getUTCDate()) + "-" + (txtWRStartDate.getMonth() + 1) + "-" + txtWRStartDate.getFullYear();  
       var dtEnd = (txtWREndDate.getUTCDate()) + "-" + (txtWREndDate.getMonth() + 1) + "-" + txtWREndDate.getFullYear();  
       $('#txtWRIdQuest').val(ret.idQuest);  
       $('#txtWRTitle').val(ret.lbQuest);  
       $('#txtWRResource').val(ret.lbPersonName);  
       $('#txtWRStartDate').val(dtBegin);  
       $('#txtWREndDate').val(dtEnd);  
       $('#txtWROrder').val(ret.sqOrder);  
       $('#hdnWRIdQuest').val("0");  
       $('#txtWREndDate').datepicker('destroy');  
       $("#txtWREndDate").datepicker(  
       {  
         dateFormat: 'dd-mm-yy',  
         minDate: $('#txtWRStartDate').val()  
       });  
     },  
     error: function (err) {  
       alert(err.responseText);  
     }  
   });  
 }  

Copy the code and try yourself. 


Tuesday, December 1, 2015

Web API in ASP.Net Web Forms - Simple Way

ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework.
So this is the basic definition of Web API and lets see how we can use it in an ASP.Net Web Forms application. You need to have Visual Studio 2013 or 2015 which may be the community edition.

1. Right click on your project and Add "Web API Controller class" which you can find under
Web > Web API



2. Add a newer folder for API Classes & You may also have a separate project too. Here I have added the classes in to a Folder.

3. You can write API Methods in this controller (Ex: SignOut)


4. Now you can write a JQuery AJAX method to call the API Method.


Remember to use valid error messages for null returns.

Happy coding.. :)