Monday 17 October 2011

Two Interfaces having same method and same parameters


Code Snippet
    public interface I1
    {
        void Method();   
    }
    public interface I2
    {
        void Method();
    }
    public class Implementor : I1, I2
    {
        public void Method()
        {
            Trace.WriteLine("Method");
        }
    }
            I1 i1 = new Implementor();
            I2 i2 = new Implementor();
            i1.Method();
            i2.Method();



If you want separate methods per interface, implement them explicitly:
Code Snippet
    public interface I1
    {
        void Method();   
    }
    public interface I2
    {
        void Method();
    }
    public class Implementor : I1, I2
    {
        #region I1 Members

        void I1.Method()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region I2 Members

        void I2.Method()
        {
            throw new NotImplementedException();
        }

        #endregion
    }

Collections

Types of Collections in .NET

There are many types of collections in the .Net Framework 2.0. The most general types of them are under the "System.Collections" namespace. All of them have the following basic methods and properties to manipulate the stored data. "Add" to add a new element, "Remove" to remove an existing element, and "Count" to get the total number of elements stored in a collection.

Non-Generic Collections

Found under the "System.Collections" namespace.
ArrayList: an array of contiguous indexed elements whose size can be increased dynamically at run time as required. You can use this data structure to store any types of data like integers, strings, structures, objects, .....
BitArray: an array of contiguous bit values (zeros and ones). Its size must be determined at design time.
SortedList: represents a list of key/value pair elements, sorted by keys and can be accessed by key and by index.
Stack: represents the data structure of last-in-first-out (LIFO).
Queue: represents the data structure of first-in-first-out (FIFO).
HashTable: represents a collection of key/value pair elements stored based on the hash code of the key.

Generic Collections


Found under the "System.Collections.Generic" namespace.
LinkedList: represents a doubly linked list data structure of a specified data type.
Dictionary: represents a collection of keys and values.
List: the generic counterpart of the ArrayList collection.
Queue: the generic counterpart of the non-generic Queue collection.
Stack: the generic counterpart of the non-generic Stack collection

Saturday 15 October 2011

Different Types of Serialization

The Microsoft .NET Framework provides an almost bewildering variety of ways to serialize an object.

XML Serialization

XML serialization allows the public properties and fields of an object to be reduced to an XML document that describes the publicly visible state of the object. This method serializes only public properties and fields—private data will not be persisted, so XML serialization does not provide full fidelity with the original object in all cases. However, because the persistence format is XML, the data being saved can be read and manipulated in a variety of ways and on multiple platforms.
The benefits of XML serialization include the following:
  • Allows for complete and flexible control over the format and schema of the XML produced by serialization.
  • Serialized format is both human-readable and machine-readable.
  • Easy to implement. Does not require any custom serialization-related code in the object to be serialized.
  • The XML Schema Definition tool (xsd.exe) can generate an XSD Schema from a set of serializable classes, and generate a set of serializable classes from an XSD Schema, making it easy to programmatically consume and manipulate nearly any XML data in an object-oriented (rather than XML-oriented) fashion.
  • Objects to be serialized do not need to be explicitly configured for serialization, either by the SerializableAttribute or by implementing the ISerializable interface.
The restrictions of XML serialization include the following:
  • The class to be serialized must have a default (parameterless) public constructor.
  • Read-only properties are not persisted.
  • Only public properties and fields can be serialized.

SOAP Serialization

SOAP serialization is similar to XML serialization in that the objects being serialized are persisted as XML. The similarity, however, ends there. The classes used for SOAP serialization reside in the System.Runtime.Serialization namespace rather than the System.Xml.Serialization namespace used by XML serialization. The run-time serialization classes (which include both the SoapFormatter and the BinaryFormatter classes) use a completely different mechanism for serialization than the XmlSerializer class.
The benefits of SOAP serialization include the following:
  • Produces a fully SOAP-compliant envelope that can be processed by any system or service that understands SOAP.
  • Supports either objects that implement the ISerializable interface to control their own serialization, or objects that are marked with the SerializableAttribute attribute.
  • Can deserialize a SOAP envelope into a compatible set of objects.
  • Can serialize and restore non-public and public members of an object.
The restrictions of SOAP serialization include the following:
  • The class to be serialized must either be marked with the SerializableAttribute attribute, or must implement the ISerializable interface and control its own serialization and deserialization.
  • Only understands SOAP. It cannot work with arbitrary XML schemas.

Binary Serialization

Binary serialization allows the serialization of an object into a binary stream, and restoration from a binary stream into an object. This method can be faster than XML serialization, and the binary representation is usually much more compact than an XML representation. However, this performance comes at the cost of cross-platform compatibility and human readability.
The benefits of binary serialization include the following:
  • It's the fastest serialization method because it does not have the overhead of generating an XML document during the serialization process.
  • The resulting binary data is more compact than an XML string, so it takes up less storage space and can be transmitted quickly.
  • Supports either objects that implement the ISerializable interface to control its own serialization, or objects that are marked with the SerializableAttribute attribute.
  • Can serialize and restore non-public and public members of an object.
The restrictions of binary serialization include the following:
  • The class to be serialized must either be marked with the SerializableAttribute attribute, or must implement the ISerializable interface and control its own serialization and deserialization.
  • The binary format produced is specific to the .NET Framework and it cannot be easily used from other systems or platforms.
  • The binary format is not human-readable, which makes it more difficult to work with if the original program that produced the data is not available.

Difference between "throw" and "throw ex" in .NET

Exception handling seems to be a common problem for .NET developers, particularly younger developers. We pretty much all know that you should wrap operations that have the potential for failing in a try/catch block if you are interested in being able to do something about the error that occurred. I'm not going to talk about the rules and guidelines for using exception handling. Instead I'm going to focus on a particular aspect of exception handling, which I tend to call exception bubbling.
Exception bubbling means that even though you are catching the exception and doing something with it, you want that exception to "bubble" up from your code to the calling code so it has a chance to do something with that exception. This is a fairly common scenario, but it has the potential to cause some major problems when you are debugging.
I'm sure most of the exception bubbling code you've seen looks similar to this
   1: try
   2: {
   3:     // do some operation that can fail
   4: }
   5: catch (Exception ex)
   6: {
   7:     // do some local cleanup
   8:     throw ex;
   9: }
This code looks perfectly reasonable and does the job. It properly catches the exception, does some local cleanup and then bubbles the exception up the chain. (A side note here is that you really shouldn't catch a general exception like this. I'm doing this for simplicity in the examples, but you should be catching specific exceptions and only those that you can do something about.)
However, how  many of you have seen code that looks like this
   1: try
   2: {
   3:     // do some operation that can fail
   4: }
   5: catch (Exception ex)
   6: {
   7:     // do some local cleanup
   8:     throw;
   9: }
There is a subtle difference between these two calls that won't be apparent until you are trying to debug the problem. That difference is in the stack trace information that gets sent with the exception.
In the first case, the stack trace is truncated below the method that failed. What this means is that when you look at the stack trace, it will look as if the exception originated in your code. This isn't always the case, particularly if you are bubbling up a CLR generated exception (like a SqlException). This is a problem known as "breaking the stack", because you no longer have the full stack trace information. This happens because you are in essence creating a new exception to throw.
By using "throw" by itself, you preserve the stack trace information. You can confirm this by looking at the IL generated for these two code blocks. This makes the difference very obvious since in the first example the IL instruction called is "throw" while in the second the instruction is called "rethrow".
Before you run and change all of your code, there are still places where "throw ex" is appropriate. There are times when you want to add information to the exception that was caught or change it into a more meaningful exception. In these instances you actually want a new exception to be thrown. Again, there are two ways you can do this. The most common way that I have seen is
   1: try
   2: {
   3:     // do some operation that can fail
   4: }
   5: catch (Exception ex)
   6: {
   7:     // do some local cleanup
   8:     throw new ApplicationException("operation failed!");
   9: }
However, this still suffers the problem of breaking the stack. Here you are generating a completely new exception and loosing any of the stack trace information from the original exception. What you really want to do is
   1: try
   2: {
   3:     // do some operation that can fail
   4: }
   5: catch (Exception ex)
   6: {
   7:     // do some local cleanup
   8:     throw new ApplicationException("operation failed!", ex);
   9: }
By passing the original exception to the ApplicationException you are preserving the original exception, and it's stack trace information, as the inner exception to your ApplicationException.
To wrap everything up
    1. Only catch exceptions if they are important to you and you need to do some sort of cleanup as a result.
    2. If you need to bubble an exception up the chain, use "throw" by itself.
    3. If you need to add information to the exception or repackage it, always pass the original exception as the inner exception

How to declare a pure virtual function in C# ?

Firstly, the class must always be declared abstract.
Secondly, the method must be declared abstract.
The following is a simple example of an abstract method:
abstract class AbstractClass
{
   public abstract void AbstractMethod();
}

Friday 14 October 2011

How does the server identify a browser ?

The first time when a browser request a page, server establishes a session and creates a session Id. Server returns this ID to the browser as part of the 'Response'. This ID is not displayed to the user. Browser will keep this internally.

There are cases where this Session ID can be visible to the users. Visit HomeDepot.com and hit any link from the home page. Then check the URL in the browser. You can see a string like BV_SessionID=@@@@0941891585.1123945660@@@@. This number represents the session id. This particular site sends the session id as a query string in the URL. If you delete this session id from the url, server will treat it as a new session and will create a new session.

But ideally, in a ASP.NET web site, there is no need to make the session id publicly visible. Server can keep it internally and send to server without annoying you.

After the browser gets a session ID, it will send the session ID to the server along with each additional page requests it makes. The webserver can identify the sessions using this Id. For some reason, if the session times out, then this ID will be no longer valid. In such cases, server will create a new session and will treat this request as a new request.

Session Management Mystery

The article is divided into two parts:
1. "Understanding Session State Modes" - to help you to understand the difference between the three modes of session state.
2. FAQ

1. Understanding Session State Modes
Storage locationInProc - session kept as live objects in web server (aspnet_wp.exe)

StateServer - session serialized and stored in memory in a separate process aspnet_state.exe).  State Server can run on another machine

SQLServer - session serialized and stored in SQL server
PerformanceInProc - Fastest, but the more session data, the more memory is consumed on the web server, and that can affect performance.

StateServer - When storing data of basic types (e.g. string, integer, etc), in one test environment it's 15% slower than InProc.  However, the cost of serialization/deserialization can affect performance if you're storing lots of objects.  You have to do performance testing for your own scenario.

SQLServer - When storing data of basic types (e.g. string, integer, etc), in one test environment it's 25% slower than InProc.  Same warning about serialization as in StateServer.

Performance tips for Out-of-Proc (OOP) modesIf you're using OOP modes (State Server or SQL Server), one of your major cost is the serialization/deserialization of objects in your session state.  ASP.NET performs the serialization/deserialization of certain "basic" types using an optimized internal method.  ("Basic" types include numeric types of all sizes (e.g. Int, Byte, Decimal, String, DateTime, TimeSpan, Guid, IntPtr and UIntPtr, etc)

If you have a session variable (e.g. an ArrayList object) that is not one of the "basic" types, ASP.NET will serialize/deserialize it using the BinaryFormatter, which is relatively slower.

So for performance sake it is better to store all session state data using one of the "basic" types listed above.  For example, if you want to store two things, Name and Address, in session state, you can either (a) store them using two String session variables, or (b) create a class with two String members, and store that class object in a session variable.  Performance wise, you should go with option (a).

To further understand this topic, please see the question in this FAQ: "How does (de)serialization work in SqlServer and State Server mode?"

RobustnessInProc - Session state will be lost if the worker process (aspnet_wp.exe) recycles, or if the appdomain restarts.  It's because session state is stored in the memory space of an appdomain.  The restart can be caused by the modification of certain config files such as web.config and machine.config,  or any change in the \bin directory (such as new DLL after you've recompiled the application using VS) For details, see KB324772. In v1, there is also a bug that will cause worker process to restart.  It's fixed in SP2 and in v1.1.  See KB321792.

If you're using IIS 6.0, you may want to go to IIS Manager, go to Application Pools/DefaultAppPool, and see if any of the parameters on the Recycling and Performance tabs are causing the IIS worker process (w3svc.exe) to shutdown.

For more details about app recycling, see my other FAQ: http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=232621

StateServer - Solve the session state loss problem in InProc mode.  Allows a webfarm to store session on a central server.  Single point of failure at the State Server.

SQLServer - Similar to StateServer.  Moreover, session state data can survive a SQL server restart, and you can also take advantage of SQL server failover cluster, after you've followed instructions in KB 311209.
CaveatsInProc - It won't work in web garden mode, because in that mode multiple aspnet_wp.exe will be running on the same machine.  Switch to StateServer or SQLServer when using web garden.  Also Session_End event is supported only in InProc mode.

StateServer
- In a web farm, make sure you have the same <machineKey> in all your web servers.  See KB 313091 on how to do it. 
- Also, make sure your objects are serializable.  See KB 312112 for details.
- For session state to be maintained across different web servers in the web farm, the Application Path of the website (For example \LM\W3SVC\2) in the IIS Metabase should be identical (case sensitive) in all the web servers in the web farm.  See KB 325056 for details

SQLServer
- In v1, there is a bug so that iif you specify integrated security in the connection string (e.g. "trusted_connection=true", or "integrated security=sspi"), it won't work if you also turn on impersonation in asp.net.  This problem is (wrongly) described in KB 324479.  Unfortunately, the "Description" and the "Cause" sections  in the KB are quite wrong and misleading.  But anyway, there is a QFE fix for it, and the fix will also be available when SP3 ships.  The problem is fixed in v1.1.
- Also, make sure your objects are serializable.  Otherwise, your request will hang!  See KB 312112 for details.  The SQLServer mode hanging problem was fixed in v1.1.  The QFE fix for KB 324479 also contains the fix for this problem.  The problem will be fixed in v1 SP3 too.
- For session state to be maintained across different web servers in the web farm, the Application Path of the website (For example \LM\W3SVC\2) in the IIS Metabase should be identical (case sensitive) in all the web servers in the web farm. See KB 325056 for details

2. FAQ's:
Question list:
Q: Session state works on some browsers, but not on others.  Why?

Q: In InProc mode, why do I lose all my session occasionally?

Q: Session states works on some web servers but not on others.

Q: Why isn't session state available?

Q: Why isn't Session_End fired?

Q: Why are my Session variables lost frequently when using InProc mode?

Q: Why does the SessionID remain the same after the Session times out or abandoned?

Q: Why does the SessionID changes in every request?

Q: What is the difference between Session.Abandon() and Session.Clear()?

Q: Is the session Timeout attribute a sliding timeout value?

Q: Can I share session state between ASP.NET and ASP pages?

Q: Can I share session state between web applications (i.e. "virtual directories" or "applications" in IIS)?

Q: What kinds of object can I store in session state?

Q: Why did my request hang after I switch to SQLServer mode?

Q: How come Response.Redirect and Server.Transfer is not working in Session_End?

Q: In Session_End, do I have a valid HttpSessionState object and HttpContext object?

Q: How do I use session state with web services?

Q: I am writing my own HttpHandler.  Why is session state not working?

Q: I am using a webfarm, and I lost session state when directed to some web servers.

Q: If using "cookieless", how can I redirect from a HTTP page to an HTTPS page?

Q: Does session state have a locking mechanism that serialize the access to state?

Q: How do I detect a session has expired and redirect it to anther page?

Q: In Session_End, I tried to do some cleanup job using SQL but it failed.  Why?

Q: I am using SQLServer mode.  Why aren't my sessions expiring?

Q: I have a frameset page which has an HTM extension, and I found out each frame it contains display a different session id on the first request.  Why?

Q: I set EnableSessionState to "ReadOnly", but in InProc mode I can still modify the session.  Why is that?

Q: I set "cookieless" to true, and now my session variables are lost after a Redirect.  Why?

Q: What are the disadvantages of setting cookieless to true?

Q: In InProc mode, I change the timeout value of a session programmatically, and that causes my Session_End to be called.  Why?

Q: In SqlServer mode, can I store my session state in a database other than tempdb?

Q: How can I avoid putting plain password for my sql connection?

Q: What SQL permissions do I need when using SqlServer mode?

Q: Can I write my own custom session state module?

Q: How does (de)serialization work in SqlServer and State Server mode?

Q: How can I secure my state server?

Q: Can I subscribe to SessionStateModule.End event using a non-global.asax handler method?

Q: Can different apps store their session state in different databases on the same SQL server?
[hr]
Q: Session state works on some browsers, but not on others.  Why?  A: Assume you aren't using cookieless, you should make sure your browsers support cookie.  Also see this KB: See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q316112

Q: In Proc mode, why do I lose all my session occasionally?A: Please see the "Robustness" section in the "Understanding session state modes" section of of this article.

Q: Session states works on some web servers but not on others. A: Maybe machine name problem. 
See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q316112

Q: Why isn't session state available?
A:
- First, check your web.config, machine.config and your page directive to make sure you have enabled session state.  
Reference:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconsessionstate.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconpage.asp

- Also, please note that session state isn't available just everywhere, anytime.  It is available only after the HttpApplication.AcquireRequestState event is called.  For example, it is NOT available in the Application_OnAuthenticateRequest handler inside global.asax.
For details, see: http://msdn.microsoft.com/library/default.asp?url=/library/enus/cpguide/html/cpconhandlingpublicevents.asp

- Lastly, make sure System.Web.SessionState.SessionStateModule is included the <httpModules> in your config files.  A common case is that SharePoint application will remove this module from their web.config files (for performance reason), and thus session state isn't available.

Q: Why isn't Session_End fired? A: This is one of the most frequently asked question. 1. Remember Session_End event is supported only in InProc mode. 
2. Session_End won't be fired if you close your browser. HTTP is a stateless protocol, and the server has no way to know if your browser has closed or not. 3. Session_End will be fired only (i) after n minutes of inactivity (n = timeout value), or (ii) if someone calls Session.Abandon(). 4. For case (i) (pt. 3), Session_End will be run by a background thread, which implies:
    a. Your code in Session_End is running using the worker process account. You may have permission problem if you're accessing resource such as database.
    b. If an error happens in Session_End, it will fail silently.
5. For case (ii), please note that in order for Session_End to be fired, your session state has to exist first.  That means you have to store some data in the session state and has completed at least one request.  
6. Again for case (ii), Session_End will be called only if the abandoned session is actually found. As a result, if you create and abandon a session inside the same request, because the session hasn't been saved and thus can't be found, Session_End won't be called.  This is a bug in v1 and upcoming v1.1.
Q: Why are my Session variables lost frequently when using InProc mode? A: Probably because of application recycle.
See http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316148
In v1, there is also a bug that will cause worker process to restart.  It's fixed in SP2 and v1.1.  See http://support.microsoft.com/default.aspx?scid=kb;EN-US;321792
For more details about app recycling, see my other FAQ:
http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=232621
Q: Why does the SessionID remain the same after the Session times out or abandoned?A:Even though the session state expires after the indicated timeout period, the session ID lasts as long as the browser session. What this implies is that the same session ID can represent multiple sessions over time where the instance of the browser remain the same.
Q: Why does the SessionID changes in every request? A: This may happen if your application has never stored anything in the session state.  In this case, a new session state (with a new ID) is created in every request, but is never saved because it contains nothing. 

However, there are two exceptions to this same session ID behavior:
- If the user has used the same browser instance to request another page that uses the session state, you will get the same session ID every time.  For details, see "Why does the SessionID remain the same after the Session times out?"
- If the Session_OnStart event is used, ASP.NET will save the session state even when it is empty.

Q: What is the difference between Session.Abandon() and Session.Clear()? A:The major practical difference is that if you call Session.Abandon(), Session_End will be fired (for InProc mode), and in the next request, Session_Start will be fired. Session.Clear( ) just clears the session data without killing it.

Q: Is the session Timeout attribute a sliding timeout value?
A: The session Timeout is a sliding expiration time, meaning whever your page access session state, the expiration time will be moved forward.  Please note that as long as a page has NOT disabled session state, it will access the session automatically when requested.

Q: Can I share session state between ASP.NET and ASP pages?
A:  No.  But there is an MSDN article on how to work around it: http://www.msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/ConvertToASPNET.asp

There are also some 3rd party solutions: 
(Disclaimer: the 3rd party solutions listed below is only for the convenience of customers, and does NOT imply any endorsement from Microsoft) http://www.consonica.com/solutions/dotnet/statestitch/index.html http://www.sessionbridge.com

Q: Can I share session state between web applications (i.e. "virtual directories" or "applications" in IIS)? A: No.  Sorry.

Q: What kinds of object can I store in session state?
A: It depends on which mode you are using:
- If you are using InProc mode, objects stored in session state are actually live objects, and so you can store whatever object you have created.
- If you are using State Server or SQL Server mode, objects in the session state will be serialized and deserialized when a request is processed.  So make sure your objects are serializable and their classes must be marked as so.  If not, the session state will not be
saved successfully.  In v1, there is a bug which makes the problem happen unnoticed in  SQLServer mode and will make your request hang.  The hanging problem is fixed in v1.1.  The QFE fix for KB 324479 also contains the fix for this problem.  The problem will be fixed in v1 SP3 too.

See this KB for more info:
http://support.microsoft.com/directory/article.asp?ID=KB;EN-US;q312112
Q: Why did my request hang after I switch to SQLServer mode?A: Please read the answer for the question: "What kinds of object can I store in session state?"

Q: How come Response.Redirect and Server.Transfer is not working in Session_End?
A: Session_End is fired internally by the server, based on an internal timer.  And thus there is no HttpRequest associted when that happens. That is why Response.Redirect or Server.Transferdoes not make sense and will not work.

Q: In Session_End, do I have a valid HttpSessionState object and HttpContext object?  A: You will have the HttpSessionState object available.  Just use 'Session' to access it. For HttpContext, it is not available because this event is not associated with any request. 

Q: Will my session state be saved when my page hit an error?  A: If you're using StateServer or SQLServer mode, for data integrity reason session state module will not save any changes to session state if there is an error.  To work around this, you can call Server.ClearError in your exception handler.   
For InProc mode, changes are made directly to the in-memory objects and so whatever changes you've made so far will stay in the memory.  However, if it's a new session, ASP.NET will not insert your session state into the internal table, and thus your session state will NOT be saved, unless you call Server.ClearError in your exception handler.

Q: How do I use session state with web services? A: The extra trick needed is on the caller side.  You have to save and store the cookies used by the web service.  See the MSDN documentation on HttpWebClientProtocol.CookieContainer property.

However, please note if you're using proxy object to call a web service from your page, the web service and your page cannot share the same session state due to architecture limitation.

This can be done if you call your web service through redirect.

Q: I am writing my own HttpHandler.  Why is session state not working?
A: Your HttpHandler has to implement the "marker" interface IRequiresSessionState or IReadOnlySessionState in order to use session state.  

Q: I am using a webfarm, and I lost session state when directed to some web servers. A: For session state to be maintained across different web servers in the web farm, the Application Path of the website (For example \LM\W3SVC\2) in the IIS Metabase should be identical (case sensitive) in all the web servers in the web farm. See KB 325056 for details.

Q: If using "cookieless", how can I redirect from a HTTP page to an HTTPS page? A: Try this:

String originalUrl = "/fxtest3/sub/foo2.aspx";
String modifiedUrl = "https://localhost" + Response.ApplyAppPathModifier(originalUrl);
Response.Redirect(modifiedUrl);
Q: Does session state have a locking mechanism that serialize the access to state?A: Session state implements a reader/writer locking mechanism:
- A page (or frame) that has session state write access (e.g. <%@ Page EnableSessionState="True" %>) will hold a writer lock on the session until the request finishes. - A page (or frame) that has session state read access (e.g. <%@ Page EnableSessionState="ReadOnly" %>) will hold a reader lock on the session until the request finishes. - Reader lock will block a writer lock; Reader lock will NOT block reader lock; Writer lock will block all reader and writer lock. - That's why if two frames both have session state write access, one frame has to wait for the other to finish first.

Q: How do I detect a session has expired and redirect it to anther page?
A: It's a much requested feature, and unfortunately there is no easy way to do it right now.  We will look into in the next major version.  In the meantime, if you are using cookie, you can store a marker in your cookie so you can tell the difference between "fresh browser + new session" and "old browser + expired session".  Below is a sample code that will redirect the page to an expired page if the session has expired.

void Session_OnStart(Object sender, EventArgs e) {
    HttpContext context = HttpContext.Current;
    HttpCookieCollection cookies = context.Request.Cookies;

    if (cookies["starttime"] == null) {
        HttpCookie cookie = new HttpCookie("starttime", DateTime.Now.ToString());
        cookie.Path = "/";
        context.Response.Cookies.Add(cookie);
    }
    else {
        context.Response.Redirect("expired.aspx");
    }
}

Q: In Session_End, I tried to do some cleanup job using SQL but it failed.  Why?
A: First, Session_End is supported only in InProc mode.  Second, Session_End is run using the account which runs the worker process (aspnet_wp.exe), which can be specified in machine.config.  Therefore, in your Session_End, if you connect to SQL using integrated security, it will use that worker process account credential to connect, and may fail depending on your SQL security settings.

Q: I am using SQLServer mode.  Why aren't my sessions expiring?
A: In SQLServer mode, session expiration is carried out by the SQL Agent using a registered job.  Make sure your SQL Agent is running.

Q: I have a frameset page which has an HTM extension, and I found out each frame it contains display a different session id on the first request.  Why?
A:The reason is that your frameset page is an HTM file instead of an ASPX file.

In normal case, if the frameset is an aspx file, when you request the page, it will first send the request to the web server, receive an asp.net session cookie (which holds the session id), and then the browser will send individual requests for the frames, and each request will carry the same session id.

However, since your frameset page is an htm file, the first request comes back without any session cookie because the page was serviced by ASP and not ASP.NET.  Then again your browser sends out individual requests for each frame.  But this time each individual request will NOT carry any session id, and so each individual frame will create its own new session.  That's why you will see different session ids in each frame.  The last request that comes back will win by overwriting the cookie written by the previous two requests.  If you do a refresh, you will see them having the same session id.

This behaviour is by-design, and the simple solution is to change your frameset page to .aspx.

Q: I set EnableSessionState to "ReadOnly", but in InProc mode I can still modify the session.  Why is that?
A: Even those enableSessionState is marked as ReadOnly, but in InProc state, the user can still modify the session.  The only difference is that the session will not be locked during the request.  This limitation is by-design.  And I sorry that it’s not documented in MSDN.

Q: I set "cookieless" to true, and now my session variables are lost after a Redirect.  Why?
A: If you're using cookieless, you must use relative path (e.g. ..\hello.aspx) instead of absolute path (e.g. \foo\bar\hello.aspx).  If you use absolute path, ASP.NET cannot preserve your session ID in the URL.

Q: What are the disadvantages of setting cookieless to true?
A: Setting Cookieless=true implies some restrictions, mainly:
1. You cannot use absolute link in your pages.
2. You have to do extra thing to switch between http and https pages in your application.
3. If your customer send a link to a friend, the URL will contain the session ID and both
users could be using the same session ID at the same time.

Q: In InProc mode, I change the timeout value of a session programmatically, and
that causes my Session_End to be called.  Why?

A:It is a a bug of InProc mode.  If you change a session's timeout to a different value,
Session_End will be called (but not Session_Start).  We will looking into that in v2 and
see if we can fix it.

Q: In SqlServer mode, can I store my session state in a database other than tempdb?
A:Yes.  See KB311209.

Q: How can I avoid putting plain password for my sql connection?
A: See sql trusted connection, or put the connection string as encrypted data in the
registry.  For details, KB 329250 and 329290.

Q: What SQL permissions do I need when using SqlServer mode?
A:The caller needs EXEC permission on the following stored procedures in ASPState:

dbo.TempGetAppID
dbo.TempGetStateItem
dbo.TempGetStateItemExclusive
dbo.TempReleaseStateItemExclusive
dbo.TempInsertStateItemLong
dbo.TempInsertStateItemShort
dbo.TempUpdateStateItemLong
dbo.TempUpdateStateItemShort
dbo.TempUpdateStateItemShortNullLong
dbo.TempUpdateStateItemLongNullShort
dbo.TempRemoveStateItem
dbo.TempResetTimeout

For version 1.1, you also need EXEC permission on the following stored procs in
ASPState:

dbo.TempGetStateItem2
dbo.TempGetStateItemExclusive2

Please note that the owner of the sprocs must have SELECT/INSERT/UPDATE/DELETE permissions on the session state tables (dbo.ASPStateTempSessions and dbo.ASPStateTempApplications).  The owner is the account which ran the installsqlstate.sql (or the persistent version (see KB311209)) to install the tables/sprocs/databases needed for sql session state.  
Also note that if your session state table lives in tempdb (by default), any permission settings on that table will be lost if you recycle SQL server.

Q: Can I write my own custom session state module?
A: In v1 and v1.1, there are very limited support for writing your own custom session state module.  I can suggest two approaches:
Approach #1 - replace SessionStateModule
In this approach, you write your own custom module and replace the original one in <httpModules>.  This way, you simply roll out your own implementation.
Drawbacks:
i. Since the constructor of HttpSessionState isn't public, you can't create your own
instance of it and stick it to HttpContext like the way ASP.NET SessionStateModule does.  Instead, you have to expose your session through some custom class, and the user can't access it through Page.Session nor HttpContext.Session.
ii. You have to implement all the code to handle session and session id creation/maintenance/expiry, etc.  That can be quite tedious.

Approach #2 - complement SessionStateModule
In this approach, you still rely on original ASP.NET SessionStateModule for session and
session id creation/maintenance/expiry, etc.  But at the same time, you write your own
custom module, and have it subscribed to at least the following HttpApplication events:
(a) PreRequestHandlerExecute - When this event happens, AcquireRequestState has been
fired already, and thus HttpContext.Session is available. In your even handler, you read
your data from your own store and copy them to HttpContext.Session.
(b) PostRequestHandlerExecute - This event is fired before ReleaseRequestState.  Your
event handler will save all the data in HttpContext.Session to your own store, and call
HttpContext.Session.Clear() to remove all items so they won't be saved by ASP.NET
session state.
(c) EndRequest - If an error occurs during the execution of the page,
PostRequestHandlerExecute might be skipped and EndRequest will be fired directly.
Your module might need to do some maintenance work here.
Please note that you shouldn't subscribe to AcquireRequestState and ReleaseRequestState like ASP.NET session state module does because if 2 modules subscribe to an event, there is no guarantee which module will get called first.
Drawbacks:
i. Your custom session data won't be available before PreRequestHandlerExecute and after PostRequestHandlerExecute.
ii. You need to figure out how to cleanup during session expiry or abandonment (in InProc, may piggyback Session_End; hard to resolve in StateServer or SQLServer mode), etc.

In the next major release ASP.NET will increase the support for customizing session state module.  Stay tuned.

Q: How does (de)serialization work in SqlServer and State Server mode?
A: SqlServer and State Server modes use serialization to store objects in a remote store. Understanding how it works will help you write your application correctly.
Assume your page foo.aspx has this piece of code:

line 1    MyClass  class = (MyClass)Session["abc"];
line 2    if (class == null) {
line 3        class = new MyClass();
line 4        Session["abc"] = class;
line 5    }
line 6
line 7    class.LastAccess = DateTime.Now; // This change will reflect in Session["abc"]
line 8
line 9    int total;
line 10  if (Session["def"] == null) {
line 11      total = 0;
line 12  }
line 13
line 14  total = total + 1;
line 15  Session["def"] = total;
line 16  total = total + 100;      // This change will NOT reflect in Session["def"]

First, let me explain one area which confuses many people.

Assume the page hits line 1 and it gets null.  Then the page will create the object (line 3), and put it in session (line 4).  Please note that what Session has is just a reference to your object (and actually the local var 'class' is also just a reference to your object).  So when you modify the object in line 7, you are actually modifying the same object pointed to by Session["abc"].  Bottom line is that 'Session["abc"]' and 'class' are just two references that point to the same object.

However, the situation in line 9-15 is different.  Line 16 has no effect on Session["def"]. It's because 'total' is a value type, and so 'Session["def"]' and 'total' are two integers which are independent of each other.

Please note that the above difference has nothing to do with session state, but with the fundamental difference between a value type (e.g. int), and an object type (e.g. MyClass).  You will have the same behavior if you replace 'Session' by, for example, a hashtable object.

Now, back to the actual question.  When do deserialization and serialization happen?

Assume you hit the above page with a brand new empty session.  After the HttpHandler is done executing your page, ASP.NET will later fire the HttpApplication.ReleaseRequestState event.  At that point, the session state module will go thru all the items in session state, serialize them all into a single binary blob, and save it to a remote store.

Now, when you hit the page again, before HttpHandler execute your page, ASP.NET will fire the HttpApplication.AcquireRequestState event.  At that point, the session state module will read the saved binary blob from the remote store, deserialize it into individual items, and stick them into Session.  But once again, what it puts into Session["abc"] is just a reference to an object (of type MyClass) which was created during the deserialization.

Q: How can I secure my state server?
A: If the state server is running on the same machine as web server, run state server in local only mode by setting the DWORD registry value HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Param ters\AllowRemoteConnection to 0.  This will prevent remote clients from connecting to the State Server.  This feature is available in v1.1, and in the to-be-shipped v1 SP3.

The state server must be protected by a firewall from external connections to truly guarantee security.  The default port is TCP 42424, although it can be changed by setting HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Param ters\Port.  Block all external connections on this port except 127.0.0.1 if in local mode, or explicitly disallow all addresses other then the connecting web server if in remote mode. 

Using IPSec is another way of protecting your state server.

Q: Can I subscribe to SessionStateModule.End event using a non-global.asax handler method?
A: The answer is NO.  When SessionStateModule raises the End event, only the method
defined in global.asax will be called. 

It's limited this way for a technical safety reason.  Suppose asp.net allows a user to use any arbitrary handler to the handle the End event.  In the case, users will usually use a page method as a handler.  When you pass in that handler during event subscription, that handler (unless it's static) is associated with the HttpApplication instance your request is running on.  Please note that HttpApplication instances are recycled to serve other requests.  So later on, when the End event gets fired, asp.net will call the handler, and the HttpApplication instance it is associated with is now being used by another request.  Such a situation will cause all sorts of problem.  So to avoid this danger, in v1 a decision was made to call only the method defined in global.asax.  Hope you all can bear with this limitation.

Q: Can different apps store their session state in different databases on the same SQL server?
A: The answer is yes.  See this KB for more details. http://support.microsoft.com/default.aspx?scid=kb;EN-US;836680

Using Hyperlink in a DataList and firing the event

<asp:DataList ID="dlst" runat="server" DataKeyField="pid" DataSourceID="SDS">
            <ItemTemplate>
            <asp:Label ID="Label" runat="server" Text='<%# Eval("pid") %>' />
            <asp:HyperLink ID="hlnk" NavigateUrl='<%# string.Format("../demo.aspx?val={0}", Eval("pid")) %>' Text="Click Me" runat="server" />
            </ItemTemplate>
         </asp:DataList>

Wednesday 12 October 2011

Params Keyword

In c# we can user the Params keyword and pass variable no of arguments to a function. It's much like using ParamArray in VisualBasic language. The syntax of params arguments is:
params datatype[] argument name

Note that the argument passed using params argument should be an single dimension array also it should be the last argument in the argument list for the function.

The params parmeter can then be accessed as an normal array.

public int sum(params int[] num)
{
int tot=0;
foreach(int i in num)
{
tot=tot+i;
}
return tot;
}

tot = sum(1,2,3);

object initializers

To get started, let's look at the standard way of initializing an object with data in C# 2.0 using constructors.  The following example creates a Person object and passes three values to its constructor.
Person p = new Person("John", "Doe", "602-123-1234");
As mentioned, C# 3.0 now supports the concept of "object initializers" which means you can easily assign data to specific properties in a type with having to create an explicit constructor (you can of course still create constructors as well). The standard C# { and } brackets are used to create object initializers.  Here's an example of using an object initializer to assign property data to a Person type.  It's nice because doing the same thing without using a constructor in C# 2.0 would have resulted in around 5 lines of code which is too many for something simple like property value assignments.
Person p = new Person() {FirstName="John",LastName="Doe",Phone="602-123-1234",City="Phoenix"};
If the Person type defines a sub object as a property you can even use object initializers to create the sub object. Here's an example of defining an Address object:
Person p = new Person()
{
    FirstName = "John",
    LastName = "Doe",
    Address = new Address()
    {
        Street = "1234 St.",
        City = "Phoenix"
    }
};

Friday 7 October 2011

Linear Search verses Binary Search

A linear search looks down a list, one item at a time, without jumping. In complexity terms this is an O(n) search - the time taken to search the list gets bigger at the same rate as the list does.
A binary search is when you start with the middle of a sorted list, and see whether that's greater than or less than the value you're looking for, which determines whether the value is in the first or second half of the list. Jump to the half way through the sublist, and compare again etc. This is pretty much how humans typically look up a word in a dictionary (although we use better heuristics, obviously - if you're looking for "cat" you don't start off at "M"). In complexity terms this is an O(log n) search - the number of search operations grows more slowly than the list does, because you're halving the "search space" with each operation.
As an example, suppose you were looking for U in an A-Z list of letters (index 0-25; we're looking for the value at index 20).
A linear search would ask:
list[0] == 'U'? No.
list[1] == 'U'? No.
list[2] == 'U'? No.
list[3] == 'U'? No.
list[4] == 'U'? No.
list[5] == 'U'? No.
... list[20] == 'U'? Yes. Finished.
The binary search would ask:
Compare list[12] ('M') with 'U': Smaller, look further on. (Range=13-25)
Compare list[19] ('T') with 'U': Smaller, look further on. (Range=20-25)
Compare list[22] ('W') with 'U': Bigger, look earlier. (Range=20-21)
Compare list[20] ('U') with 'U': Found it! Finished.
Comparing the two:
  • Binary search requires the input data to be sorted; linear search doesn't
  • Binary search requires an ordering comparison; linear search only requires equality comparisons
  • Binary search has complexity O(log n); linear search has complexity O(n) as discussed earlier
  • Binary search requires random access to the data; linear search only requires sequential access (this can be very important - it means a linear search can stream data of arbitrary size)

Sunday 2 October 2011

WCF Service Method Overloading

Just to give a little background, we cannot implement method overloading in WCF.

This is because WSDL(Web Service Definition Language) does not support features of OOPs.

If you don’t agree with me, try creating method overloading in WCF and run the same.
Without fail it will give InvalidOperationException. J

Now here we go on to implement the Method overloading WCF.

First created your overload as you do in normal C# application in Service file.

Here is the sample I have used

public class Service1 : IService1
    {
        public string Add(int v1, int v2)
        {
            return (v1 + v2).ToString();
        }

        public string Add(string v1, string v2)
        {
            return (v1 + v2);
        }
    }

Go into the Iservice1.cs

And declare the method as usual.
Just make sure to provide different Value to Name attribute to OperationContract
See the example below

        [OperationContract(Name = "AddInt")]
        string Add(int v1, int v2);

        [OperationContract(Name = "AddString")]
        string Add(string v1, string v2);

Now create a simple Console application and add the service just created.

Create an instance of the service.
Refer to image below.














We can clearly see the two method just created.

One thing to catch here.

The method name exposed on the client side is not the one created on server side but the Value
we assign to the Name attribute to OperationContract

Now you will say where is Method overloading. Very true, as of now we have just be able to perform method overloading on service side.
To reflect the same on client side we need to do another little trick.
Here we go.

Go to Service Reference.cs file


Navigate to  public partial class Service1Client : System.ServiceModel.ClientBase<WCFSampleTest.ServiceReference1.IService1>, WCFSampleTest.ServiceReference1.IService1

There you will find the two method that we have create in service.

  public string AddInt(int v1, int v2) {
            return base.Channel.AddInt(v1, v2);
        }
       
  public string AddString(string v1, string v2) {
            return base.Channel.AddString(v1, v2);
        }

Just go and change the method name from to
As displayed below.

  public string Add(int v1, int v2) {
            return base.Channel.Add(v1, v2);
        }
       
  public string Add(string v1, string v2) {
            return base.Channel.Add(v1, v2);
        }

Now as this Class ServiceClient inherits the IService interface
We need to go and change the Interface acoordingly.


Here we go


[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/AddInt", ReplyAction="http://tempuri.org/IService1/AddIntResponse",Name="AddInt")]
        string Add(int v1, int v2);       
        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/AddString", ReplyAction="http://tempuri.org/IService1/AddStringResponse",Name="AddString")]

Sometimes the 3rd Named parameter Name does not appear, if that happens go ahead and add manually.
And now your job is done.

You will now be able to see the the acutual methodOverload on the client side as well

Refer to below image