Sunday, August 24, 2008

Back to Blogging

After almost 2 months I am back to blogging. These two months went hectic for me. Lots of things happened in these two months. This all things affect a lot to my surrounding environment.

My dad is having cancer since last 4 years. He is fighting very hard to defeat the cancer. But before few months cancer came in the winning position. We were starting losing the hope, but my dad didn't. He again starts fighting with the cancer with passion. During this chaos, I got good offer from the Cybage Software, which I couldn't denied. And it was the end of a golden era of my working with Avani Cimcon Technologies (ACTL). I worked almost 2 years with ACTL. It was really a golden period of my life. Working with ACTL was the best working experience for me. But one day you have to step forward, and I took that step. It's been a pleasure working with Cybage Softwares. I became part of cybagian community from cimconiens community.

One more thing happens which made me think a lot on my and my beloved's life. On 26th of July, 2008, Ahmedabad got serial blasts. It was around 21 blasts in just 70 minutes time. The whole city and infect whole country catch into terror. Around 56 people died and 200 people injured. The biggest blast happened into the Civil Hospital (The same hospital, where my dad's treatment is going on). Fortunately all of my beloved were safe. And I am thankful to God for this. But again and again, same thought came in my mind that, why this happens? Why a human can not understand each other? Why everybody wants to kill each other? Why we can not leave peacefully with each other? And I guess nobody in this world know these answers.

Anyway, after all we have to back to our routine life also. So, now I am back to my routine life and started writing again. So below is my "To Write" list. I am going to write on below topics in near future. The list is not in sorted order.

To Write:

  • Extension methods in .Net 3.5
  • Forms Authentication in SSRS
  • Visual Studio Extensibility
  • Project Management
    • Planning
    • Scheduling
    • PERT / CPM Techniques
    • Risk Management
    • Change Management
    • Work Reporting

Tuesday, May 27, 2008

Prevent HTML Injection in ASP.Net

What is HTML Injection?

HTML Injection refers to injecting HTML code into a web servers response to alter the content to the end user. HTML injection is one of the technique for hacking and phishing. This is also known as Cross Site Scripting.

The developer must take care of these kind of security Vulnerability.

How To Prevent?

If you are a ASP.Net developer then you must know about the Validation Controls. We can prevent the HTML injection by using Custom Validation Control. It is pretty simple to write the custom logic to prevent HTML injection by using Custom Validation Control.

But I am not going to explain how to put the validation into Custom Validation control. But I am going to explain, that how we can apply the HTML validation across the application without writing redundancy code.

.Net provides facility to extend their control for our own use. We can use those extended controls into our application development.

To extend the control, we just need to inherit our class from the particular control. To create the Custom control of ASP.Net's Custom Validator control, we will need to inherit our class from the System.Web.UI.WebControls.CustomValidator class. Please find below code to create custom control of Custom Validator Control.

namespace CustomControls
{
public class CustomValidator : System.Web.UI.WebControls.CustomValidator
{
private bool m_pastInit;
private bool m_ValidateHtmlInjection = false;

#region Public Properties
[Themeable(false)]
public bool ValidateHtmlInjection
{
get
{
return this.m_ValidateHtmlInjection;
}
set
{
this.m_ValidateHtmlInjection = value;
}
}
#endregion

public CustomValidator()
{
m_pastInit = false;
}

protected override void OnInit(EventArgs e)
{
base.OnInit(e);
m_pastInit = true;
this.SetFocusOnError = true;
this.Display = ValidatorDisplay.Dynamic;
}

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (this.m_ValidateHtmlInjection)
{
this.ServerValidate += new ServerValidateEventHandler(this.HtmlInjectionServerValidator);
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "HtmlInjectionClientValidator", BuildHtmlInjectionValidationClientSideFunction());
this.ClientValidationFunction = "HtmlInjectionClientValidator";
}
}

private string BuildHtmlInjectionValidationClientSideFunction()
{
const string NEW_LINE = "\n";
const string TAB = "\t";
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
stringBuilder.Append(NEW_LINE + "<script language=\"javascript\" type=\"text/javascript\">" + NEW_LINE);
stringBuilder.Append(TAB + "function HtmlInjectionClientValidator(source,arguments){" + NEW_LINE);
stringBuilder.Append(TAB + TAB + @"var re = /<[\w]+>/;" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "if(re.test(arguments.Value))" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "{" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + "arguments.IsValid = false;" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "}" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "else" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "{" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + "arguments.IsValid = true;" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "}" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "var reHTMLPattern = new Array('<input', '<select', '<img', '<option', '<textarea', '<span', '<div', '<label', '<h', '<br', '<hr', '<table', '<tr','<th', '<td', '<a', '<body', '<html', '<script', '<link', '<meta', '<iframe', '<p', '<b', '<srtong', '<i','<dd','<dt');" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "if (String(arguments.Value) != 'undefined')" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "{" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + "for(var pattern in reHTMLPattern)" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + "{" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + TAB + "if(arguments.Value.indexOf(reHTMLPattern[pattern])>=0)" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + TAB + "{" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + TAB + TAB + "arguments.IsValid = false;" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + TAB + TAB + "break;" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + TAB + "}" + NEW_LINE);
stringBuilder.Append(TAB + TAB + TAB + "}" + NEW_LINE);
stringBuilder.Append(TAB + TAB + "}" + NEW_LINE);
stringBuilder.Append(TAB + "}" + NEW_LINE);
stringBuilder.Append("</script>" + NEW_LINE);
return stringBuilder.ToString();
}

protected void HtmlInjectionServerValidator(object source, ServerValidateEventArgs args)
{
string regEx = @"<[\w]+>";
string[] halfHtmlTags = { "<input", "<select", "<img", "<option", "<textarea", "<span", "<div", "<label", "<h", "<br", "<hr", "<table", "<tr", "<th", "<td", "<a", "<body", "<html", "<script", "<link", "<meta", "<iframe", "<p", "<b", "<srtong", "<i", "<dd", "<dt" };
bool isValid = !System.Text.RegularExpressions.Regex.IsMatch(args.Value, regEx);

if (isValid)
{
foreach (string halfHtmlTag in halfHtmlTags)
{
if (args.Value.IndexOf(halfHtmlTag) > 0)
{
isValid = false;
break;
}
}
}
args.IsValid = isValid;
}
}
}



The class, expose the property IsHtmlInjectionValidator, this property is not there in the traditional ASP.Net Custom Validator control. The validation control have client side and server side validation methods. Both method behave same. The server side validation method will be used when somebody has disabled the JavaScript support from the browser.



How To Call in ASPX Page?



To add the custom control into the ASPX page, we need to register the assembly into the page. Below is the code to register the assembly...



<%@ Register Assembly="ControlLib" Namespace="CustomControls" TagPrefix="CustomControls" %>


Below is the code for adding Custom Control into the ASPX page,



<CustomControls:CustomValidator runat="server" ID="HtmlTestCustomValidator"
ValidateHtmlInjection="true" ErrorMessage="This is HTML Injection..." ControlToValidate="InjuctionTestTextBox"></CustomControls:CustomValidator>



Other Usage



We can create SQL Injection using same methodology. I keep that for the readers. If you can find how we can do the SQL Injection validation please share with all. Otherwise I will post the SQL Injection into my next post.



Happy Coding....

Friday, May 23, 2008

10 Tips For Effective Reading And Learning


  1. Relax Before Reading
    Concentration is key factor of effective reading and learning. You will need to relax your mind and swipe off your thoughts. You brain need to be empty by thoughts before you start the reading. It is like giving space to new thoughts which are going to be arise during your reading. Your emotions need to be in neutral before reading. That will give you chance to evaluate your reading. You can do some meditation or listen to soft music before start of reading. Most of all fighter pilots and F1 racers adopt this technic before go to the flight or in race. Try it, it is really effective. 
  2. Go Slow with the Reading Never do hurry with your reading. Don't just read. Go very slow with reading. Try to understand each and every word written by author. Try to ask questions to your own self and find the answer. The more deeply you force your brain to think, the better chance you have of learning and remembering.
  3. Take Challenges of Exercises. Authors keep exercises in book for you. But what if they do that for you? You will never attempt the challenge. It will be like, you are hungry and somebody is eating on behalf of you....
  4. Write Your Own Notes In Book
    Its not bad to use Pencil to write something in your books. You can write lots of your own notes in book. It is really good practice to improve your understanding of what you are reading. Some people don't like to write anything into book, as book get spoil. In this case you can write your notes into separate notebook or even you can use sticky notes. But please write your thoughts.
  5. Give Enough Time To Your Brain
    The process of transferring the reading into long-term memory happens after stop reading. Our brain needs time to do processing. If we keep anything new or challenging during the processing time, Some of what you learned might be lost. It is recommended to read before you go to bed.
  6. What Your Brain Need?
    The performance of Brain is depend on lots of things. But we can follow few basic things to make it more efficient. The brain works best in a nice bath of fluid. Research said that Dehydration decreases cognitive function of brain. The dehydration can happened before we feel thirsty. So, keep drinking enough water while reading [But this also can cause lots of washroom visit and can break your concentration, so keep it in your own limit]. Brain also need good sound sleep. To learn at it's best, give enough sleep to you brain [At least 6-8 hours]. And last but not least, you brain need food. Please eat proper to nourish your brain. Protein, Vitamins, Sodium and Iodine are very important for your brain.
  7. Speak it out Loud.
    Speaking activates a different part of your brain. If you are trying to understand something, or increase your chance of remembering it later, say it out loud. You can discuss what you have learned or read with some of your friend (Or even with your own self in front of mirror). The discussion will bust the confidence in you. And you will see that you are learning quickly. During discussion you might come out with new ideas you had not known were there when you were reading about it.
  8. When To Stop
    You should know that when to stop reading. Your brain may overloaded. You should understand the limitation of your brain (I can not read more then 45 minutes in row, it's limitation of my brain). Now one very obvious question, how to know when to stop? If you find yourself starting to forget what you just read, or the characters start dancing on page, then that is the right time to stop reading and have some break.
  9. Feel it !!
    You must feel the importance of what you are reading or learning. Your brain need to take the reading seriously to learn effectively. Your brain will never take the reading seriously if it don't know the importance of that. 
  10. Practices
    Apply what you have read in your life. Try to put that in your everyday practice. Theoretical and practical both are the different knowledge. You need to apply your theoretical knowledge in your practical life. Coz all reading and learning will not matter until you start practicing that in your routine life. Books will show you the path (Theory) but to walk on the path (Practical) is your responsibility. I might have read everything written or printed about the Everest, but to archived the Everest is complete different thing. My reading and knowledge about the Everest only worth if, I climb and archived the Everest.

Wednesday, May 21, 2008

SQL Server Reporting Service (SSRS) - HTTP Status 401 Unauthorized Error

I am going to continue on writing article on SQL Server Reporting Services (Its because, it is providing me good fame on http://forums.asp.net, LOL smile_wink).

We have to deploy the reports on the the Reporting Services Virtual Directory (I can write the whole different article on the Reporting Deployment, but may be next time. Right now we don't want to go deep into that.). The Reporting Server Virtual Directory may exist on the different server. It is recommended to keep anonymous access off for Reports virtual directory if you are going to call reports on the web.

The anonymous access allows any user to access the page. But now when we are keeping anonymous access off for the Reports, it can create problem while fetching the report inside the Report Viewer control on any ASPX page.

The Report server will expect authorized user to access the reports. This can be done by two ways.

  1. Passing the Report Server User Credentials with the Reports.
  2. Forms Authentication on Reporting Server.

Today, I am going to explain that How can we pass the User Credentials of the Reporting Server with the report call.

We need to Create one sealed class to perform this action. This class need to be inherited from IReportServerCredential interface.

    [Serializable]
public sealed class ReportServerNetworkCredentials : IReportServerCredentials
{
#region IReportServerCredentials Members

/// <summary>
/// Provides forms authentication to be used to connect to the report server.
/// </summary>
/// <param name="authCookie">A Report Server authentication cookie.</param>
/// <param name="userName">The name of the user.</param>
/// <param name="password">The password of the user.</param>
/// <param name="authority">The authority to use when authenticating the user, such as a Microsoft Windows domain.</param>
/// <returns></returns>
public bool GetFormsCredentials(out System.Net.Cookie authCookie, out string userName,
out string password, out string authority)
{
authCookie = null;
userName = null;
password = null;
authority = null;

return false;
}

/// <summary>
/// Specifies the user to impersonate when connecting to a report server.
/// </summary>
/// <value></value>
/// <returns>A WindowsIdentity object representing the user to impersonate.</returns>
public WindowsIdentity ImpersonationUser
{
get
{
return null;
}
}

/// <summary>
/// Returns network credentials to be used for authentication with the report server.
/// </summary>
/// <value></value>
/// <returns>A NetworkCredentials object.</returns>
public System.Net.ICredentials NetworkCredentials
{
get
{
string userName = "SERVERUSERNAME";
string domainName = "DOMAIN";
string password = "somepassword";

return new System.Net.NetworkCredential(userName, password, domainName);
}
}

#endregion
}



How to Utilize the ReportServerNetworkCredentials Class in your Report call on Page_Load event...



protected void Page_Load(object sender, EventArgs e)
{
myReportViewer.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote;

// Here we are going to pass the ReportServerCredentials to the Report Viewer.
myReportViewer.ServerReport.ReportServerCredentials = new ReportServerNetworkCredentials();

ReportServerLoaction = ConfigurationManager.AppSettings["REPORT_SERVER_PATH"];
myReportViewer.ServerReport.ReportServerUrl = new Uri("http://MyReportServer/Reports/");
myReportViewer.ServerReport.ReportPath = "TempReports/MyFirstReport";
myReportViewer.ShowParameterPrompts = false;
myReportViewer.ShowPrintButton = true;

Microsoft.Reporting.WebForms.ReportParameter[] reportParameterCollection = new Microsoft.Reporting.WebForms.ReportParameter[1];
reportParameterCollection[0] = new Microsoft.Reporting.WebForms.ReportParameter();
reportParameterCollection[0].Name = "ClientID";
reportParameterCollection[0].Values.Add("49020644-63AA-4D92-81A1-8F85D49ACF67");

myReportViewer.ServerReport.SetParameters(reportParameterCollection);
myReportViewer.ServerReport.Refresh();
}



Please feel free to comment on the article. Critics are highly appreciated.

Saturday, May 10, 2008

SQL Server Reporting Services (SSRS) Versus Browser Compatibility

 

Microsoft has released SQL Server Reporting Services(SSRS) as server based report generation and development environment in 2004. It was released as SQL Server 2000 extension. SSRS has been released directly to the competition of Crystal Report and other Business Intelligence tools. The current version of SSRS is shipped with SQL Server 2005.

The file format of SSRS reports is .rdl. The RDL is XML. The RDL can be exported to PDF, XML, Excel, TIFF, CSV, HTML. Apart from this, you can call the report by simple URL.

Sounds Good...!!!!!

But, with all these coolest features of SSRS, there are plenty of bugs too. First ever bug I encounter is Browser Compatibility. There is pretty big issue with SSRS reports browser compatibility. The reports are best view in only IE6 and above. In this competitive world, we need to provide browser compatible websites. SSRS can be big hurdle in your website against browser compatibility.

We experienced a problem with the multivalue parameter dropdown in ReportViewer control in FireFox. It was working fine in IE. The calendar control and the multivalue dropdown was having problem. The problem caught me when I click on the calendar control, the calendar appears and then quickly disappeared before I can select anything. It was just in frequence of second. Wow, it was pretty quick and it became a challenging game for me to catch it. But Microsoft was very quick and I never could catch calendar.

The problem was with ReportViewer control provided by VS2005. When we call report directly in Firefox browser using report URL, it was working perfectly fine. So, finally we came to conclusion that, the problem is only due to ReportViewer control.

The solution to resolve the issue is very strange. We need to remove the DOCTYPE tag from the HTML. Removing DOCTYPE tag can create lots of issues with HTML and CSS layouts. But we have to rectify other issues.

Developers of ReportViewer control has used some nonstandard methods and attributes like onactive event. The page contains specific DOCTYPE, will not parse such events. We tried to use other DTDs like, HTML 4.0 and HTML 5.0 but nothing help. Finally we removed the DOCTYPE and problem get solve (And other design related problem start arising smile_sad).

For more in SSRS please visit Paresh Jagatiya's Weblog.

Friday, May 2, 2008

Date Format Conversion

The whole world is divided into different time zones and cultures. Every country has own style to display date and time format. Like, in USA the date has been displayed in “mm/dd/yyyy” format while in Great Britain and India the date has been displayed in “dd/mm/yyyy” format. In the web era, it’s always tough to provide culture oriented user interface. It is easy to display the date in specific format on page using ASP.net. Programmer can easily use .ToString(“dd/mm/yyyy”); to display the date into British format. But it’s not easy to store date into server with formatting.

Let’s take one scenario to understand this, I have a webpage which sense the user’s current time zone and display the date according to that. But the website is hosted on the USA based server. So the SQL Server for the Website will have the “mm/dd/yyyy” format. The SQL Server will expect the date in “mm/dd/yyyy” format. This can create problem when we provide such user interface which accept the date into “dd/mm/yyyy” format. We have to convert the date back into server’s date format before saving into database.

There is no any direct method to convert the date format with DateTime type. Probably Convert.ToDateTime() provide such facility with iFormatProvider interface. But, I really don’t know how to use that. So, I found one another work-around to convert the date in other format.

It’s very tricky to convert the date format from “dd/MM/yyyy” to “mm/dd/yyyy” in .Net 2.0. Below is function, using that programmer can convert any date in any format to the server’s date format.


public DateTime ConvertDate(string Date, string CurrentDateFormat)
{
try
{
return DateTime.ParseExact(Date, CurrentDateFormat, new CultureInfo(Thread.CurrentThread.CurrentCulture.Name));
}
catch
{
throw;
}
}


Wednesday, April 30, 2008

Something about Credit Card Validations.....

Credit Card transaction is one of the important parts of all e-commerce websites. There are lots of Credit Card Payment Gateways, which help you to authenticate credit cards. But almost all credit card payment gateways took very long time to respond back. And that might cause performance issue with our developed website.

We can reduce the payment gateway server trips by validating the credit cards in our system itself. As per my experience, most of the time the customer enters wrong credit card number and that cause the waiting time. We can validate those numbers in our system itself using JavaScript or server validators (i.e. Custom Validator in .Net). We can achieve this using Regular Expression. But first let’s start with some facts with Credit Card Numbers… There are total 5 types of widely accepted credit cards, Visa, Master Card, American Express, Diners Club and Discover. The card number pattern is depending on the type of card. The number pattern consists of the length of Card Number and the number prefix.

Card Type Prefix Length Example
Visa 4 16 4563 2214 3215 8542
Master Card 51 to 55 16 5147 2254 6585 4521
American Express

34

37

15

3422 4587 9874 125

3741 5478 9854 654

Diners Club

30

36

38

14

3000 2544 8874 12

3685 1475 8544 32

3874 8745 6654 85

Discover 6011 16 6011 7415 6587 2265

We can validate these credit cards using regular expression. Find below table of the regular expression for each credit card type.

Card Type Regular Expression
Visa ^4\d{3}-?\d{4}-?\d{4}-?\d{4}$
Master Card ^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$
American Express ^3[4,7]\d{13}$
Diners Club ^3[0,6,8]\d{12}$
Discover ^6011-?\d{4}-?\d{4}-?\d{4}$

Below is the example of a validation function of Java Script for the Credit Card Validation using Regular Expression and “mod 10” algorithm…

This code validate the credit card using Regular Expression and the "mod 10" algorithm. All the card has different prefix and the length. We are using regular expression to validate the card length and prefix. The "mod 10" validation will be performed after the card number has the right prefix and correct length. Card with even number digits and Odd number of digits validate differently. Every other digit, starting with the second digit (first digit for American Express) is added together. Then a second pass is made, again with every other digit, starting this time with the first digit (second digit for American Express). Each digit is multiplied by 2 in second pass. If the digit multiplied by 2 is greater than or equal to 10, the total minus 9 is added to the original sum from the first pass. If the digit multiplied by 2 is less than 10, then that total is added in to the original sum from the first pass. After the two passes, the total should be evenly divisible by 10.

function isValidCreditCard(cardtype, ccnumber) 
{
if (cardtype == "Visa")
{
// Prefix: 4, Lenght: 16
var regEx = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/;
}
else if (cardtype == "MasterCard")
{
// Prefix: 51-55, Length: 16
var regEx = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/;
}
else if (cardtype == "Discover")
{
// Prefix: 6011, Length: 16
var regEx = /^6011-?\d{4}-?\d{4}-?\d{4}$/;
}
else if (cardtype == "AmericanExpress")
{
// Prefix: 34 or 37, Length: 15
var regEx = /^3[4,7]\d{13}$/;
}
else if (cardtype == "Diners")
{
// Prefix: 30, 36, or 38, Length: 14
var regEx = /^3[0,6,8]\d{12}$/;
}

if (!regEx.test(ccnumber)) return false;

// Remove all dashes.
ccnumber = ccnumber.split("-").join("");

// Add even digits in even length strings or odd digits in odd length strings.
var checksum = 0;

for (var cnt=(2-(ccnumber.length % 2)); cnt<=ccnumber.length; cnt+=2)
{
checksum += parseInt(ccnumber.charAt(cnt-1));
}

for (var cnt=(ccnumber.length % 2) + 1; cnt {
var digit = parseInt(ccnumber.charAt(cnt-1)) * 2;
if (digit < 10)
{
checksum += digit;
}
else
{
checksum += (digit-9);
}
}

if ((checksum % 10) == 0)
{
return true;
}
else
{
return false;
}
}



The first character in a string is charAt(0), so that is why 1 is subtracted from the value of cnt all the time. In the first pass, if the length is even, then the length mod 2 results 0. So 2 minus 0 is 2, so the value of cnt will walk through the even numbered digits. In the first pass for strings of odd length, the length mod 2 is 1, so 2 minus 1 is 1, and the value of cnt will walk through the odd numbered digits.



This way we can validate credit card numbers client side and save some server trips.



Please feel free to comment on this post. Your feedback and suggestions will be highly appreciated.



Courtesy: