WYSIWYG

http://kufli.blogspot.com
http://github.com/karthik20522

Monday, June 15, 2009

Email using CDO Exchange c#

While working on a Report Automation project where the reports were generated at end of each day and emailed out to the business group, there was no way to test out the email content as the SMTP server were located behind an internal firewall and there was no way to access the SMTP server from my development machine. Following was the error message being thrown out:


OpenSmtp.Mail.SmtpException: ERROR - Expecting: 250. Recieved: 553 sorry, that
domain isn't in my list of allowed rcpthosts (#5.7.1)
at OpenSmtp.Mail.Smtp.CheckForError(String s, String successCode)
at OpenSmtp.Mail.Smtp.SendRecipientList(NetworkStream& nwstream, ArrayList recipients)
at OpenSmtp.Mail.Smtp.SendMail(MailMessage msg)
at Program.Sendmail(String pTo, String pSubject, String pBody)





So while looking around for alternate methods, I came across CDO [Collaboration Data Objects]. With CDO you can access Exchange services from code and also access information from Exchange such as Emails, calendars, contacts etc. CDO is basically a COM based interface for accessing Exchange. Obviously MSDN has vast amount of information about CDO and it's interfaces [http://msdn.microsoft.com/en-us/magazine/cc301434.aspx]. For quick implementation of CDO for sending emails you can use the following code:

Labels: ,

Sunday, June 14, 2009

Bot/Crawler/Spider Check Current.Request ASP.NET

While implementing a Caching Solution (LRU caching) for a project that I was working on, I realized that search engine crawlers were flooding the IIS cache which led to "out of memory exception". So for this I had to make sure that if the current request was from a Crawler then do not add to the Cache. So following is a simple implementation of WebCrawler check in C#



USAGE:

Labels: ,

ASP.NET Least Recently Used (LRU) Caching c#

I would probably assume that anyone who is or has been a web-developer would have at some point used ASP.NET caching feature. A very powerful but yet so easily implementable. As a web-developer one fine day I decided to start caching all common objects on the website such as Auto-complete data, Rewritten urls and other database intensive objects/functionality. Though it worked fine and helped us reduce our DB load by more than 30-40% but unfortunately all these 1000's of objects started building up private bytes (memory) on the server and ended up recycling IIS (App recycle) more often than before (mainly because of out-of-memory exception). Just to confirm the extent of memory build-up I wrote a simple CacheViewer handler and after 20mins of data there were more than 20K objects in the server memory being severed with a very long TTL (time to live)!! Following is a screen shot of the Cache size after 20 mins (extracted Memory dump using DebugDiag and used Tess's DotNetMemoryAnalysis script to extract the information)




In order to solve this caching problem, I had to implement LRU (Least Recently Used) based caching to cache only most used/accessed data. Though there were many implementation of LRU Caching online, but it just seemed a little complicated for such simple functionality. Following is the source code of my implementation. To my surprise it works like a charm :). So basically the way it works is that there is counter for each key in the Cache and the counter is incremented when the particular object/key is requested. Incase if the LRULimit is reached the least accessed object is replaced by the new object. Following is a screen shot of what the LRUCache looks like:




Syntax:
[Add] LRUCache.Add("keyName", object);
[Add with TTL] LRUCache.Add("keyName",object, 100);
[Get Cache] object Value = LRUCache.Get("keyName");
[Delete from Cache] LRUCache.Clear("keyName");

Labels: , ,

ASP.NET IP Address behind Proxy

While working on a Project where we needed to submit a monthly report to our clients which included the number of Clicks and number of Unique users, we always ended up having about 10-20% discrepancies when it was compared with the clients internal reports. Most of our clients were using Atlas tracking (Microsoft’s product) which made us rethink the blame game. So one of our clients was kind enough to send us their internal report and we realized that they had more unique IP users (like 20% more users IP) logged than we did. So while brainstorming our code we found that we missed to code the obvious scenario when the User’s are behind a proxy server like computers within a office n/w share the same IP.
Using Request.ServerVariables[“REMOTE_ADDR”] was only logging the Proxy address and not the actual clients IP. So we had to modify our code to the following:



"HTTP_X_FORWARDED_FOR" request variable for the most part has the actual clients address but we need to make sure the variable is not null or empty. Thus the conditional check.

Labels: ,

Friday, June 12, 2009

HTML Strip [ RegEx vs String ]

Since I work on a extremely user driven content web site, I have to make sure that there is no user inputted HTML on the page that break the CSS or the layout of the page. So we had to build a HTML Stripping functionality to strip out the HTML on the fly. We had initially used the obvious RegEx technique to strip out the HTML. But as the traffic increased the page performance/page load time started increasing. So we decided to enable trace on the page to determine the most expensive operation. So while re factoring the code we realized that the HTML stripping functionality was adding on the page load time.

So while digging around the internet to find a optimized stripping code, I came across two site. 1) DotNet Pearls [http://dotnetperls.com/remove-html-tags] and 2) StackOverflow [http://stackoverflow.com/questions/473087/string-benchmarks-in-c-refactoring-for-speed-maintainability].

Both these sites spoke about string operations vs RegEx and I decided to implement the technique mentioned on their site and following is the result from Page.Trace




As you can see from above data that there is a huge speed difference (thou it’s in milliseconds factor!!) but still much faster and there are fewer objects (string) used which is good for memory usage.

Though the original string index code worked wonders, but since we are optimizing code for performance (speed and memory usage) we can re-factor the code to use stringbuilder (better memory management).

Labels: ,

Thursday, June 11, 2009

Using Debug Diagnostics to extract and analyse Memory Dump

Download Links:

TinyGet: http://www.microsoft.com/downloads/details.aspx?FamilyID=56FC92EE-A71A-4C73-B628-ADE629C89499&displaylang=en

DebugDiag: http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en

Since I primarily work on web-applications (ASP.NET 2.0) it has become a reflexive action to check for any memory leaks or memory buildup and always try to refactor the code for smaller memory footprint and speed optimization. Since most of the primary test is done on the development machine (Windows XP IIS 5.5), I use TinyGet to simulate traffic to the particular page that I intend to test. Though I am a big fan of JMeter but I still prefer using TinyGet due to the ease-of-use.

* Before we can use TinyGet to simulate the traffic, we need to activate the DebugDiag to capture the memory of the IIS worker process. In the Debug Diagnostics tool, navigate to the "Processes" tab and right click on the w3wp.exe or aspnet_wp.exe process and select the "Monitor for leaks" option.



* Once Monitoring is tracking use tinyget to simulate request to the test page. Below command simulates 900 requests to the default.aspx page on localhost (server) and running on port 80. The "-h" parameter displays the header information of the page requested.

c:\>tinyget -srv:localhost -port:80 -uri:/default.aspx -loop:900 -h



* Once the traffic simulation is done using TinyGet, extract the memory dump by right clicking the aspnet_wp process and selecting the "create full memory dump" option.



* After extracting the memory dump file, navigate to the "Advanced Analysis" and choose "Memory Pressure Analyzer" and selected the dump file as the Data File.



By default Debug Diagnostics tool has two Analysis Scripts namely "Crash/Hang Analyzers" and "Memory pressure Analyzers". One another useful script is the "DotNetMemoryAnalysis" script written by Tess Ferrandez [http://blogs.msdn.com/tess/archive/2009/05/12/debug-diag-script-for-troubleshooting-net-2-0-memory-leaks.aspx]. Following is an example screen shot of analysis result:



Debug Diagnostics is a pretty useful and powerful tool for a quick analysis of memory and crash dump analysis. It gives you a quick peak into number of threads, memory usage and availability in the Heap and fragmentation information and lot's more data to drool about. A very handy tool for a performance and debug engineer!

Labels: , ,

Using String.Intern Benefits C#

Recently I was given a daunting task of figuring out why the web-server (IIS) was recycling every couple of hrs and when I analyzed the Crash Dump file there it was obvious that "System.String" type objects were occupying about ~250MB in memory and probably not being released or garbage collected fast enough. While some of String objects were all greater than 85000 bytes it was stored in Gen 2 [LOH - Large Object Heap] instead of Gen 0 and probably highly fragmented. So I decided to try to replicate same issue of my development machine so I hooked up the DebugDiag Memory leak process to my "aspnet_wp.exe" process (IIS 5.5 Windows XP) and simulated traffic using "tinyget" (Microsoft IIS Tool) to one of my test pages which performed similar string manipulation as the live page.



From above screen shot we can see that the String.Object type is ~10MB with 109894 objects in memory which looked quite a lot just to display data from DB and some simple string manipulation.

So while digging around MSDN [http://msdn.microsoft.com/en-us/library/system.string.intern.aspx], I was introduced to String.Intern method. Basically .NET creates a Intern Pool which contains a single reference to each unique literal string declared or created programmatically.

After I modified my application to use String.Intern (basically I added String.Intern in my property (get;set)) in my Business Entity class's and simulated the traffic again and created a new memory dump and following was the result:



As you can see from my above screen shot, the "string.object" memory and the number of instances have reduced to ~3.5MB and 21447 respectively when compared to ~10MB and over 100K objects. Though this string.intern has reduced the string.objects but one main drawback is the fact that the intern pool is not flushed until app recycles. This pool is global and objects in the pool remain for life of the app.

Following is a sample of my BusinessEntity Class:



Syntax: string.intern("string object" or "text")
The reason why I used "string.intern(value ?? "")" is because string.intern does not accept null values. Since I added string.intern in Getter's and Setter's, I had to make sure the value is not NULL and by default I set it to "". Also another example would be string concatenating the same data over and over again like the following example:



As you can see above that "/images/ratingBig-" is being concatenated or basically a constant value which over hear would make sense to use String.Intern to create only one instance of the global string object.

I personally feel that String.intern works wonders or atleast works for my situation but word of caution about it's global scope of intern pool objects.

Labels: ,

Wednesday, June 10, 2009

Certificate using Open SSL

Though creating HTTPS Certificate using IIS 7 is very simple but I needed more control over the information about the certificate. OpenSSL was the answere. OpenSSL documentation on my first read was a little complicated or a little too much information on how to create a certificate. So for all the people out there trying to create SSL certificate using OpenSSL hear is how it's done:

1) First we need to create a "key" file which holds the password phrase. The Command to generate a key file is as follows:
c:\>openssl genrsa -des3 -out kufli.key 2048
Basically the above command would create a RSA encrypted key file. The above command would require you to type in the pass-phrase.


2)Once the Key file is generated, we can go ahead and create the Certificate file. Following command is used for creating a certificate file:
c:\>openssl req -new -key kufli.key -x509 -out kufli.crt -config openssl.CNF
The above command would prompt you to fill-in Country Name, State or Province Code, Locality Name, Organization Name, Organizational Unit Name, Command Name and Email Address.


That;s it. The above command creates the Certificate file needed for Https protocol. Bellow screenshots displays the certificate information:

Labels:

FreeTextBox 3.1.6 (FTB) in Sharepoint 2003 (WebPart)

I have noticed that many programmers/users have failed to implement FreeTextBox onto Sharepoint portal (WebPart). Well it's very much possible and also easy to do so. We could skip all the Registering FTB on aspx page and RUNAT server tags and stuff like those which are hard to implement in Sharepoint Server. Below is a step-by-step implementation of FreeTextBox control on Sharepoint portal as a WebPart.

1. As per the original FTB documentation, we need to copy all the FTB support files into a directory. Over here, I have copied onto the default Sharepoint 2003 images directory.(C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\TEMPLATE\IMAGES\FreeTextBox)


2. We need to then add FreeTextBox.DLL (provided in FreeTextBox zip/setup package) onto GAC (Global Assembly Cache) either by using GACUTIL.exe or using .NET Configuration Manager in Control Panel -> Administrative Tools. Choose the appropriate FTB DLL based on .NET version being used.

Step 1 and Step 2 end's the setup process which is more simpler than the original setup methodology like referencing axd file, adding "Register" on top of the aspx page and runat server tags and adding in web.config file. What an hazel !! :)

3. First we need to add FreeTextBox reference in out WebPart Project. Add the following line of code onto ur .cs file.




4. Then need to initialise the control. Add the following code in "protected override void CreateChildControls()" method.

5. Add tBox.RenderControl(output) in "protected override void RenderWebPart(HtmlTextWriter output) method.
THAT'S IT....U have now FTB on your WebPart!!

Labels: ,