Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts
May 22, 2008

The Constant Fact : Const Vs Static ReadOnly field

One fact about constant, that we all know, is it's value can never be changed.
Here goes another one.... The constant field is statically replaced by the compiler at the compile time wherever it is found.

Means,


double
circleArea = System.Math.PI * 2 * r;
compiled to
double circleArea = 6.28318 * r;

Said that, suppose you have following expression in your one assembly "Lib"

public const int DataGridPageSize = 50;

And you are referring this assembly in your application "App". Now if you compile the solution the DataGridPageSize will be replaced by 50 in your application. But, if you change the DataGridPageSize value to 100 and compile only the assembly "Lib" and forgot to compile the application "App" then your application still has the old value 50 and not the 100 unless you recompile the "App" application.

But if you have used readonly static field you are safe in above scenario as it is not statically replaced at compile time as the constants are.

Submit this story to DotNetKicks

May 17, 2008

How To Embed Resource And Use It With WebResource Handler

Before you go deeper into this please look into my previous post Why WebResources for good reasons for using WebResources.

Three simple steps for this
.
Embed a resource in the assembly : Select your resource (javascript or image or any other) and goto properties and select "Embedded Resource" as Build Action.



Mention in your AssemblyInfo.cs file :
Mention above this resource in the AssemblyInfo file with the following syntax.
[assembly: WebResource("TestWeb.JavaScripts.common.js", "text/javascript",PerformSubstitution=true)]
Here the first parameter is the path as fully qualified name from the root namespace, like TestWeb is the root namespace and JavaScripts is the directory and then common.js is the filename. Second parameter is the MIME type for the resource being called. Third parameter tells .net that this resource contains some expression that need to be parsed and replaced with real values. We will discuss this third parameter at the end of the topic.

Call the GetWebResourceUrl() : To get the URL that can be used to call the embedded resource. The Url will be in the format
/PathFromRoot/WebResource.axd?d=P6z37LRwQoHAo_Le8MfO3Q2&t=63338169731478
Where d specify the assembly key and t specify the last time the assembly is written (compiled).

syntax of GetWebResourceUrl method is
GetWebResourceUrl(Type type, string resourceName);

I have used the following syntax to register the WebResource given javascript :
string scriptUrl = ClientScript.GetWebResourceUrl(typeof(_Default), "TestWeb.JavaScripts.common.js");
ClientScript.RegisterClientScriptInclude("Common", scriptUrl);

So we are done with how to use WebResource handler.

Now let's examine the third parameter of the WebResource attribute we have used above.
Imagine that we want to use another resource (an image) within the JavaScript file we are calling using the WebResource handler. Suppose the javascript is setting "src" of an image and that image is again a WebResource. So we will write something like following in our javascript file

document.getElementById('logo') = <%= WebResource('logo.gif')%>;


Now if you have mentioned PerformSubstitution=true for the javascript resource then all expressions like above one in your javascript will be replaced by the WebResource handler given url when your javascript will be served like

document.getElementById('logo') = "/PathFromRoot/WebResource.axd?d=P6z37LRwQoHAo_Le8MfO3Q2&t=63338169731478"

Submit this story to DotNetKicks

May 13, 2008

Why WebResources

Before we digg into "HOW TO"s about this topic let's think of "WHY WebResources?" .

Have you ever developed a control that uses some JavaScript? or image?. If not then let's exmine a case where you need to have a TextBox (web custom control) that only accepts digits means you are looking for developing one numeric text box. The quickest thing you will do is you write a class that inherits System.Web.UI.WebControl.TextBox and in that control's life cycle event you will add an HTML attribute to your control like this.Attributes.Add("onkeypress","javascript : return NumericValidationFunction()") (think that you are developing this control not only for a single web application you are working with but to provide to others if anyone needs or to sell).

Now the JavaScript function mentioned above will be written and stored in a string variable and then registered as a javascript in the PreRender method as

protected override void OnPreRender(EventArgs e) {
string numericValidationJs = "<script type='text/javascript'>function NumericValidationFunction() { your custom logic ...}</script>";
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "NumericValidationJs", numericValidationJs ,true);
}
One disadvantage (not to just supporting this topic but it really is) is that it will be rendered as part of your HTML, embedded in the page HTML itself. It increases your page size (HTML that is being rendered to the browser) and also is HeadAche for search engine spiders. Also if you have set of controls within a single library you, for maintainance purpose, need to have a single place to write this JavaScript instead of writing within each control.

Now, based on above reasons you decided to write a ".js" file. The question is to ship this file along with your control library. And if you might have used any image file, for indication that the user has not entered a number, you might also have thought of shipping that image file along with the ".js" file with this assembly.

ASP.NET 2.0 provides a very good way to achieve this and it's recognised as "WebResource handler". Where you can have your resources (like javascript and image and other resources) embedded within your assembly and then use a URL that calls a file with ".axd" extension which is being served by an HTTPHander that respond you with the resource within the assembly. So you need to ship just one ".dll" file that contains your resources within as embedded resource.

Good enough discussion on "WHY" now let's take a look into HOW TO EMBED RESOURCE AND USE IT WITH WEBRESOURCE HANDLER.

Submit this story to DotNetKicks

April 30, 2008

VIEWSTATE Serialization

The most important thing for an end user of a website is the how fast the page loads and our responsibility is to make them happy.

Frequent thing to achieve this is to review the code and write the code such a way that it performs better (in terms of processing time) but what after this ?

What if we still can increase the page serving speed. Apart from the code performance it is the ISP's speed and the size of the page that affects the download speed for a web page.


what if we can decrease the size of the page to some extent ( the size generated after the server side scripting finishes ( i mean the final rendered output)

for every server control if it's ViewState is enabled the data is kept in a viewstate in some encoded format(base64 encoded string as everyone says.)

wo when showing a control on a page keeps data in the rendered output of control as well in the viewstate along with the

state ( previous state) information ( doubles the size of final rendered output..!!)

straighaway coming to the topic we can have this VIEWSTATE buddy help us remotely ( not being rendered with the page so by decreasing the final rendered page out put size)

This can be done keeping the VIEWSTATE in the session or keep it at the server. I am keeping it at the web server as I have got the access to the web server and I have developed one web service that deletes files(holding the VIEWSTATE on the web server) after a day. In short its upto you to write code into the SaveViewState and GetViewState methods.

try the following code snippet ( just paste it in the code behind file of your aspx page)

protected override object LoadPageStateFromPersistenceMedium()
{
object _objViewState;
string _strViewState;
_strViewState = GetViewState();
LosFormatter _lFormater =
new LosFormatter();
try
{
//if(_strViewState!=String.Empty)
_objViewState = _lFormater.Deserialize(_strViewState);
//else
//_objViewState="";
}
catch{
throw new HttpException("Invalid ViewState");
}
return _objViewState;
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
StringBuilder _sBuilder =
new StringBuilder();
StringWriter _sWriter = new StringWriter(_sBuilder);
LosFormatter _lFormater = new LosFormatter();
_lFormater.Serialize(_sWriter,viewState);
_sWriter.Close();
SaveViewState(_sBuilder.ToString());
}
#region Save and Get ViewStateData
private void SaveViewState(string _vState)
{
// keep identicle files user-wise ( byadding sessionid) and page wise (for different pages by aading this.toString())
string _file = @Request.ServerVariables["APPL_PHYSICAL_PATH"]+Session.SessionID+this.ToString()+".txt";
FileStream _fS = new FileStream(_file,System.IO.FileMode.OpenOrCreate,System.IO.FileAccess.ReadWrite,System.IO.FileShare.ReadWrite);
StreamWriter _sW = new StreamWriter(_fS);
_sW.Write(_vState);
_sW.Close();
_fS.Close();
}
private string GetViewState()
{
string _file = @Request.ServerVariables["APPL_PHYSICAL_PATH"]+Session.SessionID+this.ToString()+".txt";
string _retValue=String.Empty;
if(File.Exists(_file))
{
StreamReader _sRead = new StreamReader(_file);
_retValue= _sRead.ReadToEnd();
_sRead.Close();
}
return _retValue;
}

happy programming..........

one more thing not to forget if you are using above code and storing the VIEWSTATE on web server in files.

keep a code in your Session_End in the global.asax.cs file (works when your Session State uses InProc mode) to remove the above files to keep the web-server tension free !!!

Submit this story to DotNetKicks

C# Pre Processor Directives

One of the good features of C# that we rarely use are the Pre Processor directives. Let's see how we can use them for us.

In general practice, we always write some test code in the application. As in JavaScript we use temporary alerts, in C# code behind too (or even in class library project) we use test code like temporary emailing and writing hardcode emails in the application emails. And very often this kind of code goes to production machine that is undesirable as well disastrous. To avoid this we can use the conditional compilation directives. Let's see how to use them


We are going to use three directives #define, #if, #endif. We can define the symbol in a file using the #define directive like

#define TESTCODE (this will define a symbol named TESTCODE)


And then we can write our test code within the conditional compilation #if directive as below

#if TESTCODE (if the TESTCODE symbol is defined using the #define then true, false otherwise)


// Test Code goes here.....
#endif

Also this is a very good way to handle multiple environments like in one project we had three environments like DEVELOPER, STAGE, PRODUCTION and we also had different databases. Now it may happen that we do not want the test data in our production database so that we can define these three symbols and then in the function returning the connection string we can conditionally return the appropriate connection string as below


internal string GetConnectionString() {

string conStr = "";


#if DEVELOPEMENT
conStr = "development database connection string";
#endif
#if STAGE
conStr = "Stage database connection string";
#endif
#if PRODUCTION
conStr = "Production database connection string";
#endif
return conStr;
}

HOW TO DEFINE:


So now only if you have the above line (#define TESTCODE) in your file the above conditional code will compile, not otherwise. So in case you do not want the test code to be moved to the production environment dll then just go to the file and remove the #define TESTCODE.
These conditional compilation symbols can be defined at file level or the project level. To define it at file level we can put the #define SYMBOLNAME in the file itself. To define the project level symbol follow the below steps.
Right click the .csproj (project file) -> click Properties -> go to Build tab -> find the Conditional compilation symbol and write the symbols in the text boxes. Multiple symbols can be separated by comma.
Now in ASP.NET 2.0 website this can be in the web.config file too as below
<system.codedom>
<
compilers>
<
compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
compilerOptions="/d:SYMBOL1,SYMBOL2"/>
<
/compilers>
<
/system.codedom>

USE #warning AND #error IN CODE REVIEW:

Two other important directives are #warning and #error. Let us see how can we use them. These directives can be used while reviewing the code. As when some senior programming guy reviewing the code and if he find some better alternative for a piece of code he/she can put a warning there like

#warning Method implemented incorrectly. Do not use static variables.


So whenever the code is compiled, we will find the above warning in the output window and the Error list window. If we find some bad code that is written wrongly then we can put #error MESSAGE so that the code will not be compiled ant the message will be shown in the output and the Error list window

Submit this story to DotNetKicks