Saturday, October 25, 2008

Some points on using statement in C# !

* using Statement provides standard way of using objects which implements IDisposable interface.
*generally IDisposable objects are those wraps unmanaged resources in them & hence Dispose() method can be called to release unmanahed resource.
*If IDisposable object is declared & instantiated in using statement then Dispose() method will be automatically called while control leaving the using block.
*The IDisposable can be declared & instantiated as other objects noramally & call the Dispose() method to release unmanaged resources.
*But putting it in using statement ensures that the object is disposed even when any exception occured while calling methods on object.
*This is equivalent to intantiating IDisposable object in try/ catch block & calling Dispose() in finally block.
*With in the using block the object is readonly , it cant reassigned.

Below code shows how to use IDisposable objects

//
using (StreamReader streamreader = File.OpenText(@"FilePath"))

{

string filetext = streamreader.ReadToEnd();

}

Friday, October 24, 2008

How to get HTML content of a web page for a given URL programatically with c# ?

This article shows how to grab the HTML content of a given url programatically with C#.DotNet Framework provides different classes to send http web request programatically which are under namespaec 'System.Net'.For the current implementation i'm using types 'HttpWebRequest' to send hhtp request and 'HttpWebResponse' to capture the response send by web server.
The code looks like this

static void Main(string[] args)
{
string html;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://google.com");
try
{
HttpWebResponse res =(HttpWebResponse)req.GetResponse();
if (res != null)
{
if (res.StatusCode == HttpStatusCode.OK)
{
Stream stream = res.GetResponseStream();
using (StreamReader reader = new StreamReader(stream))
{
html = reader.ReadToEnd();
}
Console.Write(html);
Console.Read();
}
res.Close();
}
}
catch { }
}


Both the HttpWebRequest & HttpWebResponse objects doesnt support any constructors.The Type WebRequest supports static method called Create() which takes URL of the web page as parameter & returns 'WebRequest' object which can be casted to 'HttpWebRequest'.
Similarly HttpWebRequest object supports method GetResponse() which returns WebResponse object which can be casted into HttpWebResponse.The response of the internet resource can be accessed from HttpWebResponse object by calling 'GetResponseStream()' which returns a stream.
If the method of the http request to internet source is POST & it is having any PostData which to be attached to http request can be sent by attaching it to HttpRequest Stream which can be accessed by calling the method GetRequestStream() of HttpWebRequest object.

Saturday, October 18, 2008

How to Compress & Decompress Strings in C# ?

This article show how to compress strings in C#. Dotnet Framework provides classes to compress the streams which can be found in 'System.IO.Compression'.The class i'm going to use is 'GZipStream'.Basically this class compresses streams , one can be use this class to compress even files.But here i'm using to compress string.

As i said class 'GZipStream' provides methods to compress streams, i'm converting my string to stream first then compressing the resulting stream.
Code looks like this
//
For Compression
public string Compress(string text)
{
byte[] buffer = Encoding.UTF8.GetBytes(text);
MemoryStream ms = new MemoryStream();
using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
{
zip.Write(buffer, 0, buffer.Length);
}
ms.Position = 0;
byte[] compressed = new byte[ms.Length];
ms.Read(compressed, 0, compressed.Length);
byte[] gzBuffer = new byte[compressed.Length + 4];
System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
return Convert.ToBase64String(gzBuffer);
}



For decompression
public string Decompress(string compressedText)
{
byte[] gzBuffer = Convert.FromBase64String(compressedText);
using (MemoryStream ms = new MemoryStream())
{
int msgLength = BitConverter.ToInt32(gzBuffer, 0);
ms.Write(gzBuffer, 4, gzBuffer.Length - 4);
byte[] buffer = new byte[msgLength];
ms.Position = 0;
using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
{
zip.Read(buffer, 0, buffer.Length);
}
return Encoding.UTF8.GetString(buffer);
}
}

Note:The compression rate will be higher for larger strings.As the number character in string increases the rate of compression will be increased.

Monday, September 15, 2008

Call WebService from javascript

This article shows how to call a web service from javascript.To understand this article better litle knowledge of following topics is required.
1)DHTML Behaviours : DHTML behaviours introduced with Microsoft Internet Explore (5.5).They are components which encapsulates specfic functionaly on a page. For more info check http://msdn.microsoft.com/en-us/library/ms531079.aspx .

2)Web Services: Web services are reusable components shared over net which can used by applications irrespective of platform & vendor.To understand the article one doesnt need to create a web service.Only thing is a web service is needed with some functionality.

To call web service we need a 'Web Service' DHTML behaviour.This behaviour provides methods like 'useService' & 'callService' to call web service.

For example say web service has a web method something like this ...

[WebMethod]
public string DemoMethod(string str)
{
return "From Web Service" + str;
}

//The method looks simple, takes a string as parameter & returns another string.
for instance say URl of the service is 'http://localhost/Service1.asmx' .
Now you hav a webservice which to be called in javascript.To call from javascript follow the following.

As i said before 'Web Service behaviour ' is needed to call the web service.This behaviour to be attached to a HTML Element on a web page.For instance say 'div' element.The mark up looks like this.
< id="Service1" style="BEHAVIOR: url(webservice.htc)" onresult="processResult()">

In the above markup id 'Service1' is required to call the methods 'useService' & 'callService' methods.Once behaviour is attached to the html elements all the members supported by the behaviour can be accessed throught the id of that element.

*Then style attribute is the where actually behaviour is attached to the element.For the current requirement we need web service behaviour ie 'webservice.htc '.For the above code should properly 'webservice.htc' file to be placed in the folder in which your web page resides.


The 'webservice.htc' file can be downloaded from MSDN website.



*Then 'onresult' attribute specifies the javascript method to be called after execution of the method is completed.In this method 'result' object preovides the result returned by web service.



After attaching the web service behaviour to html element on web page , the next step is to call methods of web service behaviour.The code looks like this ...



function init()
{
//This method is called to map the web service url to friendly name which can be used later call methods in actual web service (*.asmx file)

//first parameter to the method is actual url of web service.second parameter specifies the friendly name to this url which can be used as reference to url.

//note that id given to the html element is used to
Service1.useService("http://localhost/Service1.asmx?WSDL","myService")

//This method calls the actual method in web service.The first is the name of the method in web service.the second parameter is parameter to web method.Call to these methods are asyncronuos.So when web method execution is completed then the method specified in 'onresult' attribute is called.In this method 'result' object provides the result sent by web service.
Service1.myService.callService("HelloWorld","From javascript ")
}


//Result method

function processResult(result)
{
if(result.error)
{
//Checks for any error returned from web method
alert(result.errorDetail.string)
alert(result.errorDetail.code)
alert(result.errorDetail.raw)
}
else {
alert(result.value);
}
}


Now the init() method to be called in onload() event of the body.like


< onload="init()">

This means that web service is called when page is loaded.We can also call the web service on other events like button click.At that time 'callservice' method to be called in button click event.

But 'useservice' method to be called on 'onload' event of 'body'.


This article uses a simple web method which takes string as parameter & another string , but it can be any.

For more info on webservice behaviour check out



Saturday, August 23, 2008

How to run applications under system control programatically through C#

This Article describes how to run applications under control of o/s programatically with C#.For example one have to open notepad programatically or Internet Explorer or any other *.EXE application installed in system.
.Net framework provides 'System.Diagnostics' namespace which provides types to interact with process under o/s.For our current requirement we need 'Process' class under 'System.Diagnostics' namespace.'Process' provides static & instance methods to run an *.EXE application.Below i presented code to open notepad programatically.
//code
Process.Start("NOTEPAD");

the above piece of code opens the notepad.
Its also possible to send parameters to Process with the help of 'ProcessStartInfo' class.
For example if one wants to open internetExplorer & navigate to Google home page programatically , it can be done with following piece of code.

//code

ProcessStartInfo startinfo = new ProcessStartInfo();
startinfo.FileName = "IEXPLORE";
startinfo.Arguments = "Http://google.com";
Process.Start(startinfo);

When you run above code , a new IE window will be opened with Google home page.

How to Add Context Menu Item to Internet Explorer Browser.

This article describes about how to add custom context menu item to Internet Explorer Browser.This essentialy involves registry modifications.This can be done either manually or programatically.Manually means opening system registry & editing manually.Programatically in the sense writing code to edit registry.For programatic editing i'l present C# coding.
Context Menu:
Context menu is menu which will be opened on mouse right buttom click on a window.
Note:To understand this article better a basic understanding of system registry is essential.
Manul Way:
Internet Explorer has its own default context menu.If one wants to add custom menu item to this default menu,microsoft is providing a way to do this.This typically requires 'System registry' modifications.To add a context item open system registry.For this follow below navigation.

Start --> Run --->regedit
Then registry will be opened.In registry navigate to following path 'HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt'
Under 'MenuExt' key add a new key.The name of this key will be the name of menu item in Internet Explorer.For instance say 'MyMenuItem'.Once key is added a default string value is added to this key.The Value of the this default string should be the path of the Script file which will be executed when 'MyMenuItem' is clicked.For instance say 'C:\MyMenuItem.htm'This may be .js file or .htm file.Once this is done the menu item will appear in Internet Explorer Context Menu.
Now 'MyMenuItem' item will be appear in IE context menu.One can perform what ever the action needed by adding appropriate script in sript file.The window can be accessed from the script as follows.
//gets the window
var window=external.menuArguments ;
//to get the document object
var doc=window.document ;
//perform action .....

This is how a context menu item can be added to IE manually.If context menu item to work for specific items like Selected text,image or links, this can be done by specifying 'Context' value for 'MyMenuItem' key in registry.
To Add content specific context menu item to IE, Add 'DWORD' type value to 'MyMenuItem' key & name it 'Context'.The value of the 'Context' decides to which content the menu item is available.
The valid values of 'Context' & their corresponding contents are given below.
  1. 0x1 (Hex) -- this default
  2. 0x2 (hex)-- for images (means this context menu item available for only images )
  3. 0x4 " ---for controls
  4. 0x8 " --- for tables
  5. 0x10 ---for selected text
  6. 0x20 ---for Anchors(links)

Note:before editing Registry ensure that Registry back up is taken.

For More Info about Customising IE Check http://msdn.microsoft.com/en-us/library/bb735853(VS.85).aspx

Programatic Way:

.net framework provides built in API to work with system registry.

Note:Make sure that namespace 'Microsoft.Win32' is accessible to your code

RegistryKey registryKey;
registryKey = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Internet Explorer\MenuExt");

//Adding registry key 'MyMenuItem'
RegistryKey addSourceKey = registryKey.CreateSubKey("MyMenuItem");

//Set Default string value to Path of the script file
addSourceKey.SetValue("", "C:\\MyMenuItem.htm");
addSourceKey.Close();
registryKey.Close();

Monday, July 28, 2008

Capturing HTTP Status codes with 'WebBrowserControl'

WebBrowser is a winndows forms control which allows you to add web browsing capabilities to windows application developed with .net technology(i.e C#.net or vb.net).This control acts in a similar way to Internet Explorer Browser.Its supports methods & events to navigate to url ,properties to work with HTML Document Object Model(DOM) etc.But it doesn't allow to capture directly some things programatically,for example HTTP status codes.If the requested web page is not found then HTTP Status code '404' is shown on web browser,but with if u want capture this status code programatically,its not straight farward. Actually WebBrowser windows forms control is wrapper WebBrowser ActivexControl in 'Microsoft Internet Control(SHDocVw.dll)' library which is a COM component.WebBrowser windows forms control doesnt support all the events supported by Activex Control (Web Browser).Activex Control supports 'NavigateError' event which will be raised when any error occured while navigating to url.By handling this event one can get HTTP Status codes for a requested url.
To capture 'NavigateError' with windows forms 'Web Browser' control a work around is there.Its possible to cast windows forms 'Web Browser' into Activex control.The under lying ActiveXControl of windows forms WebBrowser control can be accessed through a property called 'ActiveXInstance'.The code looks like this

Code :
Following library to added to the project.
* 'Microsoft Internet Control(SHDocVw.dll) which can be found under COM tab of Add Reference window.


System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
System.Windows.Forms.WebBrowserBase wb1;
SHDocVw.WebBrowser wb2 = (SHDocVw.WebBrowser)wb.ActiveXInstance;
wb2.NavigateError += new DWebBrowserEvents2_NavigateErrorEventHandlerwb2_NavigateError);

//event handler for NavigateError event
void wb2_NavigateError(object pDisp, ref object URL, ref object Frame, ref object StatusCode, ref bool Cancel)
{
throw new NotImplementedException();
}

If any error occured while navigating to URL the 'NavigateError' will be raised.The 'StatusCode'
parameter of the event handler gives the HTTP Status code.
Note:Not all the HTTP status codes can be get through this approach.As the event is raised only when an error occured while navigating,only HTTP status codes related to error can be accesed.Following are the list of HTTP Status codes that can be accessed.
HTTP_STATUS_BAD_GATEWAY (502)
HTTP_STATUS_BAD_METHOD (405)
HTTP_STATUS_BAD_REQUEST (400)
HTTP_STATUS_CONFLICT (409)
HTTP_STATUS_DENIED (401)
HTTP_STATUS_FORBIDDEN (403)
HTTP_STATUS_GATEWAY_TIMEOUT (504)
HTTP_STATUS_GONE (410)
HTTP_STATUS_LENGTH_REQUIRED (411)
HTTP_STATUS_NONE_ACCEPTABLE (406)
HTTP_STATUS_NOT_FOUND (404)
HTTP_STATUS_NOT_SUPPORTED (501)
HTTP_STATUS_PAYMENT_REQ (402)
HTTP_STATUS_PRECOND_FAILED (412)
HTTP_STATUS_PROXY_AUTH_REQ (407)
HTTP_STATUS_REQUEST_TIMEOUT (408)
HTTP_STATUS_REQUEST_TOO_LARGE (413)
HTTP_STATUS_RETRY_WITH (449)
HTTP_STATUS_SERVER_ERROR (500)
HTTP_STATUS_SERVICE_UNAVAIL (503)
HTTP_STATUS_UNSUPPORTED_MEDIA (415)
HTTP_STATUS_URI_TOO_LONG (414)
HTTP_STATUS_VERSION_NOT_SUP (505)

FAQS

This post is meant to give some information in question & answer pattern so that it'll be usefull for quick reference.I'l keep on adding stuff to these post when ever i found a deserving thing.

1)Tips to Optimize performance of stored procedure.
A developer has wrriten a stored procedure.Its working fine, in the sense its giving the expected output for set of given input.But you've got a feedback that the performance is not good & you take neccesary action to improove the performance.In such a scenario following the below things may lead to better performance.

a)Set 'SET NOCOUNT ON' before your stored procedure.This will stop sending number of rows affected as a result of this stored procedure.This can reduce network traffic.

b)calling stored procedures using thier fully qualified names may increase performance.Using fully qualifies names increases the chances reusing of stored procedure execution plans.

c)use RETURN statement whereever possible.This stops sqlserver building resultset.

e)dont use 'sp_' for stored procedures which are in databases other than in master database.If u hav a stored procedure with 'sp_' as a prefix , sql server will look in to the master database first & then looks for other database.

f)If the StoredProcedure is very large ,then consider to split it to many sub storedprocedure's .the reason is when any structural changes occured or bulk updates or inserts or deletes occured in table associated with stored procedure then stored procedure will recompile.If it is splitted in to many sub stored procedure's chances are more that few sub sp's will be recompiled.

g)Try to avoid using temporary tables in sp.using of temp tables will reduces the chances of reusing the execution plan of stored procedure.

h)try to avoid using DDL in stored procedure.using DDL in sp again redces the chance of reusing execution plan.

Checking for the above things helps in tracing where to refactor.

Tuesday, July 22, 2008

How to promt for system restart after installing Windows Installer Package(*.msi) developed in Visual Studio

With Visual Studio one can develop variety of applications.After developing application the next step comes deploying application.For this Visual Studio supports project template called 'Setup and Deployment Projects'.With this project template one can develop setup.exe for any application developed using Visual Studio.But for some applications after deploying unless the system is restarted the application wont work as expected.The typical example for this kind of scenario is if application contains any registry additions.In such a cases its always recommended to prompt for system restart soon after completing installation.
This article describes how to achieve this.To do this one has to edit properties of *.msi file.*.msi file is created in Debug or Release folder once your setup & deployment project in visual studio is bulit.
To edit properties of *.msi file one can do it in 'Orca' editor.
'Orca' is a tool which can be used to edit properties of Windows Installer Packages(*.msi) .For more info on Orca visit http://msdn.microsoft.com/en-us/library/aa370557.aspx

The next step is edit properties .open your *msi file in Orca editor with the help of 'Open' menu item in 'File' menu.Take a look at image below.

After opening *.msi file in Orca editor you will find 'Table' pane on right side of the editor.Under 'Table' select 'Property' to select property table.This shows the list of properties & its values in right pane.Right click the 'Property' header & select 'Add Row' menu item.Then a pop up will be opened where name & value of property give.Give 'REBOOT' as name & 'Force' as value & save.Its done now.If you install that package(*.msi) then after completion of installing a automatic popup will appear prompting for system restart.Chekout image below.

Saturday, July 12, 2008

Cookie issue with 'HttpWebRequest' object

Recently i have a requirement to programatically get the HTML mark up of a given url with C# coding.After a bit R&D work i found 'HttpWebRequest' object in 'System.Net' namespace will server my purpose.Following lines of code can get the HTML mark up of a given URL.

//code

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("url");
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
Stream str = res.GetResponseStream();
StreamReader streader = new StreamReader(str);
string htmlContent = streader.ReadToEnd();

in the above code 'htmlContent' contains the HTML mark up of the 'url' .Ideally this code should work for the all the urls.But there may be cases where the requested source is moved to some other web server & the request is redirected to new location by attaching some cookie to incoming request , in such a scenarios the above code wont work, it'l give excetion the reason is by default cookies are disable for 'HttpWebRequest'

The solution for this problem is to enable cookies for 'HttpWebRequest' object.This can be done with following piece of code.

//code
req.CookieContainer = new CookieContainer();

Note: setting of 'CookieContainer' property of 'HttpWebRequest' should be done before calling 'GetResponse()' method.

With this code cookies are enable for 'HttpWebRequest'.

Disable Close option on system menu for Windows Forms

This article decsribes about how to disable a close option of system menu for a windows form with C#.This can be done by calling win API functions.

First let me explain what 'System menu' is ?

System menu:
-----------------
In windows o/s for any opened window a button is added in the task bar.When clicked on the button the window will be opened if it is minimised and vice versa.When right clicked on task bar button a menu will be opened,technically this menu is know as 'System menu',also called as Window menu'.This menu can also be accesed by by right clicking on title bar of the window & clicking on the icon on title bar of windThis consists menu options like 'Close','Minimise','Maximise','Size','Move','Restore'.All these terms are self explanatory.Check out the image below.


The present article explains about how disable any option in system menu.
Win API provides set of methods to deal with menu & submenus.These methods can be used to modify the menu's.
Following are the winAPI functions needed for requirement
1)GetSystemMenu ---- get access to system menu.
2)EnableMenuItem --- modifies system menu.


To call this methods from C# code .Net framework provides a way called 'Platform Invoke'.

PlatformInvoke:

Platform Invoke concept allows to call methods from managed code which are in unmanaged DLL's. For more information on this ckeck out
"http://msdn.microsoft.com/en-us/library/aa288468.aspx"

To call a method in managed code first that method to be declered with [DLLImport] attribure.This attribute should be applied to methods which are declared in managed code & actually implemented in unmanaged DLL.The code looks like this .

[DllImport("user32.dll")] private static extern IntPtr GetSystemMenu(IntPtr Hmenu, bool Brevert);

Parameters Info:
---first parameter of above function is a handle to window.
---Second parameter must be 'false' so that the menu can be modified.

Note:DllImport atribute takes Dll name as parameter.In our case its 'user32.dll'

[DllImport("user32.dll")] private static extern bool EnableMenuItem(IntPtr Hmenu, uint Uposition, uint UEnable);

Parameters Info:
--Fisrt parameter is the handle to system menu.Its return value of the method 'GetSystemMenu'
--Second parameter specifies the which menu item to be modified.Value of the parameter also depends upon the value of 'UEnable' parameter.
--third parameter is combination of values which indicates whether the menu item is enabled, disabled, or grayed.The combination of possible vales are MF_BYCOMMAND or MF_BYPOSITION and MF_ENABLED, MF_DISABLED, or MF_GRAYED.

MF_BYCOMMAND
Indicates that uIDEnableItem gives the identifier of the menu item. If neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified, the MF_BYCOMMAND flag is the default flag.
MF_BYPOSITION
Indicates that uIDEnableItem gives the zero-based relative position of the menu item.
MF_DISABLED
Indicates that the menu item is disabled, but not grayed, so it cannot be selected.
MF_ENABLED
Indicates that the menu item is enabled and restored from a grayed state so that it can be selected.
MF_GRAYED
Indicates that the menu item is disabled and grayed so that it cannot be selected.
values for the above constants can be found in winuser.h header file in windows platform SDK.

These declarations to be made in global area of the code part of the form(like form.cs).
After declaring the methods required the next step is to call that method in approptiate place.In this case form load event is appropriate place to call the methods.

//Code in form load
EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);

Values for the constants
-------------------------
private const int MF_BYPOSITION = 0x00400;
private const int MF_GRAYED = 0x000001;
private const int MF_ENABLED = 0x000000;
private const int MF_BYCOMMAND = 0x00000;
private const int SC_CLOSE = 0xF060;
private const int SC_SIZE = 0xF000;
private const int SC_MOVE = 0xF010;
private const int SC_MAXIMIZE = 0xF030;

After running the code system menu for the form looks something like this.