Saturday, August 9, 2008

Create an RSS feed using ASP.NET 2.0

using System.Data.SqlClient;
using System.Text;
using System.Xml;

// Clear any previous output from the buffer
Response.Clear();
Response.ContentType = "text/xml";
XmlTextWriter xtwFeed = new XmlTextWriter(Response.OutputStream, Encoding.UTF8);
xtwFeed.WriteStartDocument();
// The mandatory rss tag
xtwFeed.WriteStartElement("rss");
xtwFeed.WriteAttributeString("version", "2.0");
// The channel tag contains RSS feed details
xtwFeed.WriteStartElement("channel");
xtwFeed.WriteElementString("title", "Feedpedia Today's World News");
xtwFeed.WriteElementString("link", http://amitmetkar.blogspot.com/);
xtwFeed.WriteElementString("description", "The latest news and journals from all over the world.");
xtwFeed.WriteElementString("copyright", "Copyright 2008-09 Amit Merkar All rights reserved.");
// Objects needed for connecting to the SQL database
SqlConnection SqlCon;
SqlCommand SqlCom;
SqlDataReader SqlDR;
// Edit to match your connection string
SqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());
// Edit to match your stored procedure or SQL command
SqlCom = new SqlCommand("GetTodaysHeadlines", SqlCon);
SqlCom.CommandType = CommandType.StoredProcedure;
if (SqlCon.State == ConnectionState.Closed)
{
SqlCon.Open();
}
SqlDR = SqlCom.ExecuteReader();
// Loop through the content of the database and add them to the RSS feed while (SqlDR.Read()){
xtwFeed.WriteStartElement("item");
xtwFeed.WriteElementString("title", SqlDR["Title"].ToString());
xtwFeed.WriteElementString("description", SqlDR["Description"].ToString());
xtwFeed.WriteElementString("link", "http://www.feedpedia.com/View.aspx?View=" + SqlDR["ID"]);
xtwFeed.WriteElementString("pubDate", SqlDR["Date"].ToString());
xtwFeed.WriteEndElement();
}
SqlDR.Close();
SqlCon.Close();
// Close all tags
xtwFeed.WriteEndElement();
xtwFeed.WriteEndElement();
xtwFeed.WriteEndDocument();
xtwFeed.Flush();
xtwFeed.Close();
Response.End();

Dot.NET/C#/VB.NET/ASP.NET Interview Questions

1. Does C# support multiple inheritance?
No, use interfaces instead
2. What’s the implicit name of the parameter that gets passed into the class’ set method?
Value, and its datatype depends on whatever variable we’re changing
3. What’s the top .NET class that everything is derived from?
System.Object.
4. How’s method overriding different from overloading?
When overriding, you change the method behavior for a derived class. Overloading simply involves having a method with the same name within the class.
5. What is CLR?
The .NET Framework provides a runtime environment called the Common Language Runtime or CLR (similar to the Java Virtual Machine or JVM in Java), which handles the execution of code and provides useful services for the implementation of the program. CLR takes care of code management at program execution and provides various beneficial services such as memory management, thread management, security management, code verification, compilation, and other system services. The managed code that targets CLR benefits from useful features such as cross-language integration, cross-language exception handling, versioning, enhanced security, deployment support, and debugging.
6. What is CTS?
Common Type System (CTS) describes how types are declared, used and managed in the runtime and facilitates cross-language integration, type safety, and high performance code execution.
7. What is CLS?
The CLS is simply a specification that defines the rules to support language integration in such a way that programs written in any language, yet can interoperate with one another, taking full advantage of inheritance, polymorphism, exceptions, and other features. These rules and the specification are documented in the ECMA proposed standard document, "Partition I Architecture", http://msdn.microsoft.com/net/ecma
8. What is strong name?
A name that consists of an assembly's identity—its simple text name, version number, and culture information (if provided)—strengthened by a public key and a digital signature generated over the assembly.
9. What is Application Domain?
The primary purpose of the AppDomain is to isolate an application from other applications. Win32 processes provide isolation by having distinct memory address spaces. This is effective, but it is expensive and doesn't scale well. The .NET runtime enforces AppDomain isolation by keeping control over the use of memory - all memory in the AppDomain is managed by the .NET runtime, so the runtime can ensure that AppDomains do not access each other's memory. Objects in different application domains communicate either by transporting copies of objects across application domain boundaries, or by using a proxy to exchange messages.
10. What is serialization in .NET? What are the ways to control serialization?
Serialization is the process of converting an object into a stream of bytes. Deserialization is the opposite process of creating an object from a stream of bytes. Serialization/Deserialization is mostly used to transport objects (e.g. during remoting), or to persist objects (e.g. to a file or database).Serialization can be defined as the process of storing the state of an object to a storage medium. During this process, the public and private fields of the object and the name of the class, including the assembly containing the class, are converted to a stream of bytes, which is then written to a data stream. When the object is subsequently deserialized, an exact clone of the original object is created. Binary serialization preserves type fidelity, which is useful for preserving the state of an object between different invocations of an application. For example, you can share an object between different applications by serializing it to the clipboard. You can serialize an object to a stream, disk, memory, over the network, and so forth. Remoting uses serialization to pass objects "by value" from one computer or application domain to another. XML serialization serializes only public properties and fields and does not preserve type fidelity. This is useful when you want to provide or consume data without restricting the application that uses the data. Because XML is an open standard, it is an attractive choice for sharing data across the Web. SOAP is an open standard, which makes it an attractive choice. There are two separate mechanisms provided by the .NET class library - XmlSerializer and SoapFormatter/BinaryFormatter. Microsoft uses XmlSerializer for Web Services, and uses SoapFormatter/BinaryFormatter for remoting. Both are available for use in your own code.
11. What are Satellite Assemblies?
Satellite assemblies are often used to deploy language-specific resources for an application. These language-specific assemblies work in side-by-side execution because the application has a separate product ID for each language and installs satellite assemblies in a language-specific subdirectory for each language. When uninstalling, the application removes only the satellite assemblies associated with a given language and .NET Framework version. No core .NET Framework files are removed unless the last language for that .NET Framework version is being removed.
12. What is Global Assembly Cache (GAC) and what is the purpose of it?
Each computer where the common language runtime is installed has a machine-wide code cache called the global assembly cache. The global assembly cache stores assemblies specifically designated to be shared by several applications on the computer. You should share assemblies by installing them into the global assembly cache only when you need to.
13. What is Reflection in .NET?
All .NET compilers produce metadata about the types defined in the modules they produce. This metadata is packaged along with the module (modules in turn are packaged together in assemblies), and can be accessed by a mechanism called reflection. The System.Reflection namespace contains classes that can be used to interrogate the types for a module/assembly.
14. What is the managed and unmanaged code in .net?
The .NET Framework provides a run-time environment called the Common Language Runtime, which manages the execution of code and provides services that make the development process easier. Compilers and tools expose the runtime's functionality and enable you to write code that benefits from this managed execution environment. Code that you develop with a language compiler that targets the runtime is called managed code; it benefits from features such as cross-language integration, cross-language exception handling, enhanced security, versioning and deployment support, a simplified model for component interaction, and debugging and profiling services
15. What are Namespaces?
The namespace keyword is used to declare a scope. This namespace scope lets you organize code and gives you a way to create globally-unique types. Even if you do not explicitly declare one, a default namespace is created. This unnamed namespace, sometimes called the global namespace, is present in every file. Any identifier in the global namespace is available for use in a named namespace. Namespaces implicitly have public access and this is not modifiable.
16. What are the access-specifiers available in c#?
Private, Protected, Public, Internal, Protected Internal.
17. Advantage of ADO.Net?
ADO.NET Does Not Depend On Continuously Live Connections
Database Interactions Are Performed Using Data Commands
Data Can Be Cached in Datasets
Datasets Are Independent of Data Sources
Data Is Persisted as XML
Schemas Define Data Structures
18. Difference between OLEDB Provider and SqlClient ?
SQLClient .NET classes are highly optimized for the .net / sqlserver combination and achieve optimal results. The SqlClient data provider is fast. It's faster than the Oracle provider, and faster than accessing database via the OleDb layer. It's faster because it accesses the native library (which automatically gives you better performance), and it was written with lots of help from the SQL Server team.
19. Differences between dataset.clone and dataset.copy?
Clone - Copies the structure of the DataSet, including all DataTable schemas, relations, and constraints.Does not copy any data Copy - Copies both the structure and data for this DataSet.
20. In a Webservice, need to display 10 rows from a table. So DataReader or DataSet is best choice?
WebService will support only DataSet.
21. What is Remoting?
The process of communication between different operating system processes, regardless of whether they are on the same computer. The .NET remoting system is an architecture designed to simplify communication between objects living in different application domains, whether on the same computer or not, and between different contexts, whether in the same application domain or not.
22. What’s the difference between System.String and System.StringBuilder classes?
System.String is immutable; System.StringBuilder was designed with the purpose of having a mutable string where a variety of operations can be performed.
23. What’s a delegate?
A delegate object encapsulates a reference to a method. In C++ they were referred to as function pointers.
24. What’s an interface class?
It’s an abstract class with public abstract methods all of which must be implemented in the inherited classes
25. What is the transport protocol you use to call a Web service
SOAP is the preferred protocol.

SQL Server Interview Questions

1. What’s the difference between a primary key and a unique key?
Both primary key and unique enforce uniqueness of the column on which they are defined. But by default primary key creates a clustered index on the column, where are unique creates a nonclustered index by default. Another major difference is that, primary key doesn’t allow NULLs, but unique key allows one NULL only.
2. Write a SQL Query to find first Week Day of month?
SELECT DATENAME(dw, DATEADD(dd, - DATEPART(dd, GETDATE()) + 1, GETDATE())) AS FirstDay
3. How to find 6th highest salary from Employee table

SELECT TOP 1 salary FROM (SELECT DISTINCT TOP 6 salary FROM employee
ORDER BY salary DESC) a ORDER BY salary

4. What is a join and List different types of joins.
Joins are used in queries to explain how different tables are related. Joins also let you select data from a table depending upon data from another table. Types of joins: INNER JOINs, OUTER JOINs, CROSS JOINs. OUTER JOINs are further classified as LEFT OUTER JOINS, RIGHT OUTER JOINS and FULL OUTER JOINS.
5. How can I enforce to use particular index?
You can use index hint (index=index_name) after the table name. SELECT au_lname FROM authors (index=aunmind)
6. What is sorting and what is the difference between sorting and clustered indexes?
The ORDER BY clause sorts query results by one or more columns up to 8,060 bytes. This will happen by the time when we retrieve data from database. Clustered indexes physically sorting data, while inserting/updating the table.
7. What are the differences between UNION and JOINS?
A join selects columns from 2 or more tables. A union selects rows.
8. What is the Referential Integrity?
Referential integrity refers to the consistency that must be maintained between primary and foreign keys, i.e. every foreign key value must have a corresponding primary key value
9. What is the row size in SQL Server 2000?
8060 bytes.
10. How to determine the service pack currently installed on SQL Server?
The global variable @@Version stores the build number of the sqlservr.exe, which is used to determine the service pack installed. eg: Microsoft SQL Server 2000 - 8.00.760 (Intel X86) Dec 17 2002 14:22:05 Copyright (c) 1988-2003 Microsoft Corporation Enterprise Edition on Windows NT 5.0 (Build 2195: Service Pack 3)
11. What is the purpose of UPDATE STATISTICS?
Updates information about the distribution of key values for one or more statistics groups (collections) in the specified table or indexed view.
12. What is the use of SCOPE_IDENTITY() function?
Returns the most recently created identity value for the tables in the current execution scope.
13. What are the different ways of moving data/databases between servers and databases in SQL Server?
There are lots of options available, you have to choose your option depending upon your requirements. Some of the options you have are: BACKUP/RESTORE, detaching and attaching databases, replication, DTS, BCP, logshipping, INSERT...SELECT, SELECT...INTO, creating INSERT scripts to generate data.
14. How do you transfer data from text file to database (other than DTS)?
Using the BCP (Bulk Copy Program) utility.
15. What's the difference between DELETE TABLE and TRUNCATE TABLE commands?
DELETE TABLE is a logged operation, so the deletion of each row gets logged in the transaction log, which makes it slow. TRUNCATE TABLE also deletes all the rows in a table, but it won't log the deletion of each row, instead it logs the deallocation of the data pages of the table, which makes it faster. Of course, TRUNCATE TABLE can be rolled back.
16. What is a deadlock?
Deadlock is a situation when two processes, each having a lock on one piece of data, attempt to acquire a lock on the other's piece. Each process would wait indefinitely for the other to release the lock, unless one of the user processes is terminated. SQL Server detects deadlocks and terminates one user's process.
17. What is a LiveLock?
A livelock is one, where a request for an exclusive lock is repeatedly denied because a series of overlapping shared locks keeps interfering. SQL Server detects the situation after four denials and refuses further shared locks. A livelock also occurs when read transactions monopolize a table or page, forcing a write transaction to wait indefinitely.
18. How to restart SQL Server in single user mode?
From Startup Options :- Go to SQL Server Properties by right-clicking on the Server name in the Enterprise manager. Under the 'General' tab, click on 'Startup Parameters'. Enter a value of -m in the Parameter.
19. Does SQL Server 2000 clustering support load balancing?
SQL Server 2000 clustering does not provide load balancing; it provides failover support. To achieve load balancing, you need software that balances the load between clusters, not between servers within a cluster.
20. What is DTC?
The Microsoft Distributed Transaction Coordinator (MS DTC) is a transaction manager that allows client applications to include several different sources of data in one transaction. MS DTC coordinates committing the distributed transaction across all the servers enlisted in the transaction.
21. What is DTS?
Microsoft® SQL Server™ 2000 Data Transformation Services (DTS) is a set of graphical tools and programmable objects that lets you extract, transform, and consolidate data from disparate sources into single or multiple destinations.
22. What are defaults? Is there a column to which a default can't be bound?
A default is a value that will be used by a column, if no value is supplied to that column while inserting data. IDENTITY columns and timestamp columns can't have defaults bound to them.
23. What are the constraints ?
Table Constraints define rules regarding the values allowed in columns and are the standard mechanism for enforcing integrity. SQL Server 2000 supports five classes of constraints. NOT NULL , CHECK, UNIQUE, PRIMARY KEY, FOREIGN KEY.
24. What is Transaction?
A transaction is a sequence of operations performed as a single logical unit of work. A logical unit of work must exhibit four properties, called the ACID (Atomicity, Consistency, Isolation, and Durability) properties, to qualify as a transaction.
25. What is Isolation Level?
An isolation level determines the degree of isolation of data between concurrent transactions. The default SQL Server isolation level is Read Committed. A lower isolation level increases concurrency, but at the expense of data correctness. Conversely, a higher isolation level ensures that data is correct, but can affect concurrency negatively. The isolation level required by an application determines the locking behavior SQL Server uses. SQL-92 defines the following isolation levels, all of which are supported by SQL Server: Read uncommitted (the lowest level where transactions are isolated only enough to ensure that physically corrupt data is not read).
Read committed (SQL Server default level).
Repeatable read.
Serializable (the highest level, where transactions are completely isolated from one another).

Export GridView to Excel

Here is the complete code to Export GridView to Excel:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

public partial class ExportGridView : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{ GridView1.DataSource = BindData();
GridView1.DataBind();
}
}

private string ConnectionString
{
get { return @"Server=localhost;Database=Northwind;
Trusted_Connection=true"; }
}

private DataSet BindData()
{
// make the query
string query = "SELECT * FROM Categories";
SqlConnection myConnection = new SqlConnection(ConnectionString);
SqlDataAdapter ad = new SqlDataAdapter(query, myConnection);
DataSet ds = new DataSet();
ad.Fill(ds, "Categories");
return ds;
}

protected void Button1_Click(object sender, EventArgs e)
{
Response.Clear();
Response.AddHeader("content-disposition", "attachment;
filename=FileName.xls");
Response.Charset = "";
// If you want the option to open the Excel file without saving than
// comment out the line below
// Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.xls";
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite =
new HtmlTextWriter(stringWrite);
GridView1.RenderControl(htmlWrite);
Response.Write(stringWrite.ToString());
Response.End();
}

public override void VerifyRenderingInServerForm(Control control)
{
// Confirms that an HtmlForm control is rendered for the
specified ASP.NET server control at run time.
}
}

Encrypting Configuration Information in ASP.NET 2.0 Applications

Introduction
When creating ASP.NET 2.0 applications, developers commonly store sensitive configuration information in the Web.config file. The cannonical example is database connection strings, but other sensitive information included in the Web.config file can include SMTP server connection information and user credentials, among others. While ASP.NET is configured, by default, to reject all HTTP requests to resources with the .config extension, the sensitive information in Web.config can be compromised if a hacker obtains access to your web server's file system. For example, perhaps you forgot to disallow anonymous FTP access to your website, thereby allowing a hacker to simply FTP in and download your Web.config file.

Encryption Options
Protecting configuration sections in ASP.NET 2.0 uses the provider model, which allows for any implementation to be seamlessly plugged into the API. The .NET Framework 2.0 ships with two built-in providers for protecting configuration sections:

The Windows Data Protection API (DPAPI) Provider (DataProtectionConfigurationProvider) - this provider uses the built-in cryptography capabilities of Windows to encrypt and decrypt the configuration sections. By default this provider uses the machine's key. You can also use user keys, but that requires a bit more customization. Refer to How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI for more information on this process. Since the keys are machine- or user- specific, the DPAPI provider does not work in settings where you wan to deploy the same encrypted configuration file to multiple servers.
RSA Protected Configuration Provider (RSAProtectedConfigurationProvider) - uses RSA public key encryption to encrypt/decrypt the configuration sections. With this provider you need to create key containers that hold the public and private keys used for encrypting and decrypting the configuration information. Refer to How To: Encrypt Configuration Sections in ASP.NET 2.0 Using RSA for more information. You can use RSA in a multi-server scenario by creating exportable key containers.
You can also create your own protected settings providers, if needed.
In this article we'll only explore using the DPAPI provider using machine-level keys. This is, by far, the simplest approach since it doesn't require creating any keys or key containers, or ensuring access and permission rights to user-level keys. Of course, it has the downside that an encrypted configuration file can only be used on the web server that performed the encryption in the first place; furthermore, using the machine key would allow the encrypted text to be decrytable by any website on the web server.

Programmatically Encrypting Configuration Sections
The System.Configuration.SectionInformation class abstractly represents a configuration section. To encrypt a configuration section simply use the SectionInformation class's ProtectSection(provider) method, passing in the name of the provider you want to use to perform the encryption. To access a particular configuration section in your application's Web.config file, use the WebConfigurationManager class (in the System.Web.Configuration namespace) to reference your Web.config file, and then use its GetSection(sectionName) method to return a ConfigurationSection instance. Finally, you can get to a SectionInformation object via the ConfigurationSection instance's SectionInformation property.

This jumble of words should be made clearer by a simple code example (which I'm taking directly from David Hayden's blog entry Encrypt Connection Strings AppSettings and Web.Config in ASP.NET 2.0 - Security Best Practices:

private void ProtectSection(string sectionName,
string provider)
{
Configuration config =
WebConfigurationManager.
OpenWebConfiguration(Request.ApplicationPath);
ConfigurationSection section =
config.GetSection(sectionName);
if (section != null &&
!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection(provider);
config.Save();
}
}
private void UnProtectSection(string sectionName)
{
Configuration config =
WebConfigurationManager.
OpenWebConfiguration(Request.ApplicationPath);
ConfigurationSection section =
config.GetSection(sectionName);
if (section != null &&
section.SectionInformation.IsProtected)
{
section.SectionInformation.UnprotectSection();
config.Save();
}
}

This method David has created - ProtectSection(sectionName, provider) - can be called from an ASP.NET page, passing in a section name (like connectionStrings) and a provider (like DataProtectionConfigurationProvider), and it opens the Web.config file, references the section, invokes the ProtectSection(provider) method of the SectionInformation object, and saves the configuration changes.

The UnProtectSection(provider) method decrypts a particular configuration section. Here only the section to decrypt needs to be passed in - we don't need to bother with the provider because that information is stored in the markup accompanying the encrypted section (i.e., in the above example, the "connectionStrings" section, after being encrypted, included the provider: connectionStrings configProtectionProvider="DataProtectionConfigurationProvider").

Keep in mind that once the data is encrypted, when it's read from an ASP.NET page (i.e., reading the connection string information from a SqlDataSource control or programmatically, via ConfigurationManager.ConnectionStrings[connStringName].ConnectionString), ASP.NET automatically decrypts the connection string and returns the plain-text value. In other words, you don't need to change your code one iota after implementing encryption.

Using the aspnet_regiis.exe Command-Line Tool
You can also encrypt and decrypt sections in the Web.config file using the aspnet_regiis.exe command-line tool, which can be found in the %WINDOWSDIR%\Microsoft.Net\Framework\version directory. To encrypt a section of the Web.config using the DPAPI machine key with this command-line tool, use:

-- Generic form for encrypting the Web.config file for a particular website...
aspnet_regiis.exe -pef section physical_directory ?prov provider
-- or --
aspnet_regiis.exe -pe section -app virtual_directory ?prov provider
-- Concrete example of encrypting the Web.config file for a particular website...
aspnet_regiis.exe -pef "connectionStrings" "C:\Inetpub\wwwroot\MySite" ?prov "DataProtectionConfigurationProvider"
-- or --
aspnet_regiis.exe -pe "connectionStrings" -app "/MySite" ?prov "DataProtectionConfigurationProvider"
-- Generic form for decrypting the Web.config file for a particular website...
aspnet_regiis.exe -pdf section physical_directory
-- or --
aspnet_regiis.exe -pd section -app virtual_directory
-- Concrete example of decrypting the Web.config file for a particular website...
aspnet_regiis.exe -pdf "connectionStrings" "C:\Inetpub\wwwroot\MySite"
-- or --
aspnet_regiis.exe -pd "connectionStrings" -app "/MySite"

You can also specify that aspnet_regiis.exe should perform encryption/decryption on the machine.config file instead. See the technical documentation for the ASP.NET IIS Registration Tool (Aspnet_regiis.exe) for more information on the available command-line switches.

Encrypting Cookie Data with ASP.NET

Overview of Cryptography in .NET
First, let's just acknowledge that encryption is really complicated. Frankly, it's supposed to be complicated because that is what makes it secure. And, by the way, I want to state here that I am in no way an encryption expert. There are probably only a handful of people that fully understand the intricacies of the math involved, and half of them probably wrote the cryptography classes for the .NET Framework.
Fortunately, we don't have to understand the intricacies to take advantage of encryption because the .NET Framework gives us a simple way to access the power of the best and most secure algorithms. Before we begin encrypting our cookie data, we should have a little discussion about the cryptography classes and which ones are appropriate for securing our cookies.

What Is Encryption Exactly?
In the simplest terms, encryption is the process of taking a target string of characters (bytes, more specifically) and converting it into another string of characters so that by examination, the original characters cannot be deciphered. This process is performed with a second string of characters known as a "key". In technical terms, this key is mathematically "mashed" into the original string over many complex and compounded iterations. In addition, sometimes another string of characters, known as an "initialization vector", is "mangled" into the target string before the key is mashed. This helps to prevent obvious patterns in the target string from being revealed by mashing alone. Of course, the mashing and mangling is not permanent. If the key and the initialization vector remain intact, then the algorithms can use them in reverse to unmangle and unmash the original data.
The effectiveness or "strength" of the encryption is determined by the size of the key used. The larger the key, the stronger the encryption. Typical key sizes are 64 bit (8 bytes), 128 bit (16 bytes), 192 bit (24 bytes), 256 bit (32 bytes) and 512 bit (64 bytes). The only way to crack most of these algorithms is by sheer brute force, where an attacker creates a program to test every single possible key combination. For even the 64-bit option, there are 72,057,594,037,927,936 possible combinations (2^56 - 8 bits are held for parity). So basically, unless you have a very powerful computer, you are going to be waiting awhile to crack even the weakest key.

Cryptography Patterns
There are two basic approaches for handling data encryption: symmetric (or private key) and asymmetric (or public key). In symmetric cryptography techniques, both sides of the data exchange (the encryptor and decryptor) must have access to a single secret private key.
In asymmetric encryption, one side (the decryptor) requests a public key from the encryptor. The encryptor creates a public key and sends it to the requestor. Then the encryptor uses the public key to create a second unique private key that it holds on to. This new private key is used to encrypt the message sent to the decryptor, who then uses the public key to decrypt the message. If encrypted data must be sent in the other direction then the other side will create a new public key and sends it along in a reciprocal fashion. This asymmetric technique is used by SSL to secure HTTP transmissions.
For our cookie encryption purposes, we will use the symmetric approach since both the encryption and decryption will take place in the same application on the server; therefore, we only need one private key that we will keep secure in the compiled code of our cryptographic utility class.

Cryptographic Service Providers
The .NET Framework provides 4 cryptographic algorithms that extend from the base SymmetricAlgorithm class:
1. System.Security.Cryptography.DES (Data Encryption Standard)
2. System.Security.Cryptography.TripleDES (Triple Data Encryption Standard)
3. System.Security.Cryptography.RC2
4. System.Security.Cryptography.Rijndael

Key Size Considerations
DES is one of the weaker encryption methods because its key size is limited to 64 bits. However, for our cookie purposes, this level of encryption is probably sufficient. TripleDES, which, believe it or not, performs the encryption three times, also has a larger key size. The length of the key must be either 128 or 192 bits - two to three times larger. TripleDES is significantly more secure. Deciding which algorithm to use should not only be based on your desire for stronger encryption but also by the size of the cookies you require. You will notice in our example application that encrypted data will grow in size. And of course, the larger the key, the larger the resulting data. This is an important consideration since cookie data is restricted to 4kb.
An alternative is to store data that you only need to persist temporarily in hidden input tags. Of course, this is exactly what ViewState does in ASP.NET. In addition, ViewState offers some built-in encryption. The ViewState of a Web form, by default, uses hash functions from some of the asymmetric algorithms to garble the content. This is not fully secure. However, you can configure your ASP.NET application or individual pages to use more secure encryption on the ViewState - specifying the same TripleDES algorithm we discussed earlier. Here is an article on MSDN on how to do just that:

http://msdn.microsoft.com/library/en-us/dnaspnet/html/asp11222001.asp?frame=true
if you are carrying that much data around in cookies, you really should reconsider you Web-application design. Remember, each request made of the server will need to pass this cookie blob back, unnecessarily chewing up bandwidth.
Finally, encryption is a processor intensive activity. The more data you are encrypting/decrypting or the stronger your algorithm, the more server resources you will require, potentially slowing down the entire site.

The CryptoStream Object
One of the things you may find hard to understand at first is that all encryption and decryption in .NET is handled through the CryptoStream object. I know you are thinking that all we need to do is convert a few strings. Why do we need to mess with complicated streams. Well, from the broader scope of cryptographic issues and from the design emphasis of the .NET Framework, using streams really makes sense. Nearly all access (IO) to external resources handled by the .NET Framework is done through the use of streams. While it is not in the System.IO namespace, the CryptoStream object inherits from the System.IO.Stream object.
The major advantage of using streams is that they can be chained together. This is particularly useful when performing file operations or accessing other network services. For instance, you can open a socket to a network service and stream data that is simultaneously being encrypted. The following link provides an example of DES provider encrypting a file through streams.
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemSecurityCryptographyDESClassTopic.asp?frame=true
So, in order to work with strings as a stream, we need to utilize a special class called a MemoryStream. This will allow us to handle strings as streams and flow them through the CryptoStream for processing.

Creating Cryptography Utility Class

Imports System.Diagnostics
Imports System.Security.Cryptography
Imports System.Text
Imports System.IO
Public Class CryptoUtil
'8 bytes randomly selected for both the Key and the Initialization Vector
'the IV is used to encrypt the first block of text so that any repetitive
'patterns are not apparent
Private Shared KEY_64() As Byte = {42, 16, 93, 156, 78, 4, 218, 32}
Private Shared IV_64() As Byte = {55, 103, 246, 79, 36, 99, 167, 3}
'24 byte or 192 bit key and IV for TripleDES
Private Shared KEY_192() As Byte = {42, 16, 93, 156, 78, 4, 218, 32, _
15, 167, 44, 80, 26, 250, 155, 112, _
2, 94, 11, 204, 119, 35, 184, 197}
Private Shared IV_192() As Byte = {55, 103, 246, 79, 36, 99, 167, 3, _
42, 5, 62, 83, 184, 7, 209, 13, _
145, 23, 200, 58, 173, 10, 121, 222}
'Standard DES encryption
Public Shared Function Encrypt(ByVal value As String) As String
If value <> "" Then
Dim cryptoProvider As DESCryptoServiceProvider = _
New DESCryptoServiceProvider()
Dim ms As MemoryStream = New MemoryStream()
Dim cs As CryptoStream = _
New CryptoStream(ms, cryptoProvider.CreateEncryptor(KEY_64, IV_64), _
CryptoStreamMode.Write)
Dim sw As StreamWriter = New StreamWriter(cs)
sw.Write(value)
sw.Flush()
cs.FlushFinalBlock()
ms.Flush()
'convert back to a string
Return Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length)
End If
End Function
'Standard DES decryption
Public Shared Function Decrypt(ByVal value As String) As String
If value <> "" Then
Dim cryptoProvider As DESCryptoServiceProvider = _
New DESCryptoServiceProvider()
'convert from string to byte array
Dim buffer As Byte() = Convert.FromBase64String(value)
Dim ms As MemoryStream = New MemoryStream(buffer)
Dim cs As CryptoStream = _
New CryptoStream(ms, cryptoProvider.CreateDecryptor(KEY_64, IV_64), _
CryptoStreamMode.Read)
Dim sr As StreamReader = New StreamReader(cs)
Return sr.ReadToEnd()
End If
End Function
'TRIPLE DES encryption
Public Shared Function EncryptTripleDES(ByVal value As String) As String
If value <> "" Then
Dim cryptoProvider As TripleDESCryptoServiceProvider = _
New TripleDESCryptoServiceProvider()
Dim ms As MemoryStream = New MemoryStream()
Dim cs As CryptoStream = _
New CryptoStream(ms, cryptoProvider.CreateEncryptor(KEY_192, IV_192), _
CryptoStreamMode.Write)
Dim sw As StreamWriter = New StreamWriter(cs)
sw.Write(value)
sw.Flush()
cs.FlushFinalBlock()
ms.Flush()
'convert back to a string
Return Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length)
End If
End Function
'TRIPLE DES decryption
Public Shared Function DecryptTripleDES(ByVal value As String) As String
If value <> "" Then
Dim cryptoProvider As TripleDESCryptoServiceProvider = _
New TripleDESCryptoServiceProvider()
'convert from string to byte array
Dim buffer As Byte() = Convert.FromBase64String(value)
Dim ms As MemoryStream = New MemoryStream(buffer)
Dim cs As CryptoStream = _
New CryptoStream(ms, cryptoProvider.CreateDecryptor(KEY_192, IV_192), _
CryptoStreamMode.Read)
Dim sr As StreamReader = New StreamReader(cs)
Return sr.ReadToEnd()
End If
End Function
End Class
Note that our keys are initialized at the top as an array of bytes. Also, note that I am using numeric constants in these arrays. If you choose to do the same, be sure to keep the values greater than or equal to zero and less than or equal to 255. This is the allowable range for a byte value.
In the class, we have 2 pairs of functions for encrypting and decrypting under both the DES and TripleDES providers. On the encrypt functions, the final byte array in the Memory Stream buffer is converted back to a string using the ToBase64String function. The reverse is done on the decrypt functions with the FromBase64String function.

Creating a Cookie Utility Class
Our next step is to create a simple class for setting and retrieving either plain cookies or those with encryption on top. Again we use series of shared methods to simplify the setting and getting of cookie data, allowing you to handle cookie data with one line of code. Imports System.Web


Public Class CookieUtil
'SET COOKIE FUNCTIONS *****************************************************
'SetTripleDESEncryptedCookie - key & value only
Public Shared Sub SetTripleDESEncryptedCookie(ByVal key As String, _
ByVal value As String)
'Convert parts
key = CryptoUtil.EncryptTripleDES(key)
value = CryptoUtil.EncryptTripleDES(value)
SetCookie(key, value)
End Sub
'SetTripleDESEncryptedCookie - overloaded method with expires parameter
Public Shared Sub SetTripleDESEncryptedCookie(ByVal key As String, _
ByVal value As String, ByVal expires As Date)
'Convert parts
key = CryptoUtil.EncryptTripleDES(key)
value = CryptoUtil.EncryptTripleDES(value)
SetCookie(key, value, expires)
End Sub
'SetEncryptedCookie - key & value only
Public Shared Sub SetEncryptedCookie(ByVal key As String, _
ByVal value As String)
'Convert parts
key = CryptoUtil.Encrypt(key)
value = CryptoUtil.Encrypt(value)
SetCookie(key, value)
End Sub
'SetEncryptedCookie - overloaded method with expires parameter
Public Shared Sub SetEncryptedCookie(ByVal key As String, _
ByVal value As String, ByVal expires As Date)
'Convert parts
key = CryptoUtil.Encrypt(key)
value = CryptoUtil.Encrypt(value)
SetCookie(key, value, expires)
End Sub
'SetCookie - key & value only
Public Shared Sub SetCookie(ByVal key As String, ByVal value As String)
'Encode Part
key = HttpContext.Current.Server.UrlEncode(key)
value = HttpContext.Current.Server.UrlEncode(value)
Dim cookie As HttpCookie
cookie = New HttpCookie(key, value)
SetCookie(cookie)
End Sub
'SetCookie - overloaded with expires parameter
Public Shared Sub SetCookie(ByVal key As String, _
ByVal value As String, ByVal expires As Date)
'Encode Parts
key = HttpContext.Current.Server.UrlEncode(key)
value = HttpContext.Current.Server.UrlEncode(value)
Dim cookie As HttpCookie
cookie = New HttpCookie(key, value)
cookie.Expires = expires
SetCookie(cookie)
End Sub
'SetCookie - HttpCookie only
'final step to set the cookie to the response clause
Public Shared Sub SetCookie(ByVal cookie As HttpCookie)
HttpContext.Current.Response.Cookies.Set(cookie)
End Sub
'GET COOKIE FUNCTIONS *****************************************************
Public Shared Function GetTripleDESEncryptedCookieValue(ByVal key As String) _
As String
'encrypt key only - encoding done in GetCookieValue
key = CryptoUtil.EncryptTripleDES(key)
'get value
Dim value As String
value = GetCookieValue(key)
'decrypt value
value = CryptoUtil.DecryptTripleDES(value)
Return value
End Function
Public Shared Function GetEncryptedCookieValue(ByVal key As String) As String
'encrypt key only - encoding done in GetCookieValue
key = CryptoUtil.Encrypt(key)
'get value
Dim value As String
value = GetCookieValue(key)
'decrypt value
value = CryptoUtil.Decrypt(value)
Return value
End Function
Public Shared Function GetCookie(ByVal key As String) As HttpCookie
'encode key for retrieval
key = HttpContext.Current.Server.UrlEncode(key)
Return HttpContext.Current.Request.Cookies.Get(key)
End Function
Public Shared Function GetCookieValue(ByVal key As String) As String
Try
'don't encode key for retrieval here
'done in the GetCookie function
'get value
Dim value As String
value = GetCookie(key).Value
'decode stored value
value = HttpContext.Current.Server.UrlDecode(value)
Return value
Catch
End Try
End Function
End Class


You'll notice most of the set functions are overloaded to provide an addition parameter for a cookie expiration date. Not setting the expiration will keep the cookie only for the browser session in memory. To set a permanent cookie, set an expiration date for a point in the future.
Also, note that the encryption functions handle the encryption of both the data and the key. It is important to encrypt the key as well since that can expose information about the nature of the data. For instance, if your key was "UserID", then it might be safe to assume that your encrypted value is a numeric string, giving an attacker an advantage.

Creating Web Forms To Set Cookies
In our sample application, I have two forms. The first (and the default form) is SetCookies.aspx, and the second is GetCookies.aspx

SetCookies.aspx Web Form

The set cookies form is quite simple. We have a single text box and a button to post the value back to the server.


When the Save Cookie button is clicked, the form returns to the server and initiates the following server-side event:


Protected Const COOKIE_KEYNAME = "MyKey"
Private Sub btnSaveCookie_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnSaveCookie.Click
CookieUtil.SetCookie(COOKIE_KEYNAME, _
txtCookieValue.Text, Now.AddDays(30))
CookieUtil.SetEncryptedCookie(COOKIE_KEYNAME, _
txtCookieValue.Text, Now.AddDays(30))
CookieUtil.SetTripleDESEncryptedCookie(COOKIE_KEYNAME, _
txtCookieValue.Text, Now.AddDays(30))
Response.Redirect("GetCookies.aspx")
End Sub


Using a constant for the cookie key name and the value submitted in the text box, we set three cookies. First, a standard unencrypted cookie. Second, a cookie encrypted with DES, and third, a cookie encrypted with Triple DES.


GetCookies.aspx Web Form
The Get Cookies Web Form is doing a little more work behind the scene to show you what happens to your cookie data.

In the Page_Load event, we retrieve the cookie data using our CookieUtil accessor functions. Then, finally we dump out the contents of the entire cookie collection, just to prove there was no funny business.


Protected Const COOKIE_KEYNAME = "MyKey"
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
Dim DESCookieKey As String = CryptoUtil.Encrypt(COOKIE_KEYNAME)
Dim TripleDESCookieKey As String = _
CryptoUtil.EncryptTripleDES(COOKIE_KEYNAME)
lblCookieName.Text = COOKIE_KEYNAME
lblStandardCookieValue.Text = _
CookieUtil.GetCookieValue(COOKIE_KEYNAME)
lblDESEncryptedValue.Text = _
CookieUtil.GetCookieValue(DESCookieKey)
lblDESDecryptedValue.Text = _
CookieUtil.GetEncryptedCookieValue(COOKIE_KEYNAME)
lblTripleDESEncryptedValue.Text = _
CookieUtil.GetCookieValue(TripleDESCookieKey)
lblTripleDESDecryptedValue.Text = _
CookieUtil.GetTripleDESEncryptedCookieValue(COOKIE_KEYNAME)
End Sub

Cautions about Cookies
So there you have it - a fairly simple yet powerful way to encrypt your cookie data. But before I leave you, I want to review a few issues to watch out for when using cookies.

  • Your entire cookie collection is limited to 4 kilobytes in size. This includes key, the space for key names, and other related data.
  • The size of your cookie data will increase when encrypted. Make sure you do not run over the limit.
  • Cookies are sent to the server every time a request is made to the server. Therefore, if you are lugging large cookies back and forth, you are using additional bandwidth and server processing resources.
  • Encrypting large amounts of data can impact application performance.
  • Any initial values supplied by your user cannot be encrypted unless you use SSL on your site. For instance, in our sample set cookies form, the initial value was passed in the clear to the server.
  • Cookies can be blocked or deleted at anytime by your users. If the use of cookies is critical to the operation of your application, you may need to find ways to work around users that can't or won't permit them.

Creating Custom Web Controls

There are many controls in Microsoft Visual Studio 2005 that certainly save you lots of development time, but there are always opportunities for you to build your own controls to save even more development time. Many business problems require custom controls to simplify the development solution. Custom controls are typically required to obtain different functionality, new functionality, or the combined functionality of several controls. This chapter covers the types of custom controls that you can create in ASP.NET 2.0.


Custom Web Control Types
There are three primary custom control types that will be covered in this chapter: user controls, custom Web controls, and composite controls. The following is a description of these controls: 1.user control A user control is a template control that provides extra behavior to allow constituent (individual) controls to be added to the user control in the Graphical User Interface (GUI) designer. These controls are added to the user control’s template file, the .ascx file. The .ascx file is similar to the Web page’s .aspx file and can have a code-behind page. To enable reuse, the .ascx and code-behind files must be included in each project that requires the user control.
2.custom Web control A custom Web control is a control that inherits from a Web control, where you either write all of the code to render the control, or inherit it from an existing Web control and provide extra behavior as necessary. The class file can be compiled to a .dll that can be shared among applications and can optionally be installed in the global assembly cache (GAC). 3.composite control A composite control is a custom Web control that can contain constituent controls; the constituent controls are added to the composite control via code to the class file that defines the control. The class file can be compiled to a .dll that can be shared among applications and can optionally be installed in the GAC.


Working with User Controls


Creating a User Control
User controls have a standard naming convention, which uses an .ascx extension to ensure that the control is not executed in a stand-alone fashion. You can create a user control in Visual Studio 2005 by choosing Website, Add New Item, Web User Control. On the surface, it appears that a new Web page was added. However, a quick glance at the HTML reveals a Control directive instead of a Page directive, as follows:

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="MyControl.ascx.vb" Inherits="MyControl" %>
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyControl.ascx.cs" Inherits="MyControl" %>

All text and controls that are added to this user control are rendered on the page that the control is added to. For example, a Label called lblName and a TextBox called txt-Name are placed on the user control, as shown below, and the user control can be added to any Web page where required.

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="MyControl.ascx.vb" Inherits="MyControl" %>

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyControl.ascx.cs" Inherits="MyControl" %>


Creating a User Control from a Web Page
In addition to explicitly creating a user control, you can also convert a Web page to a user control. The primary benefit is that you can do your prototyping and testing without having to deal with placing the control on a Web page.
The procedure for converting a Web page to a user control is as follows:
Remove the HEAD ,BODY ,FORM and begin and end tags.
Change the @Page directive at the top of the file to an @Control directive.
Change the file extension of your Web page from .aspx to.ascx.
In the @Control directive, change Inherits="System.Web.UI.Page" to Inherits="System.Web.UI.UserControl".

Adding a User Control to a Page
You can add a user control to a Web page by simply dragging it from the Solution Explorer and dropping it on a Web page. When you add the user control to the page, a look at the HTML reveals the following additions to the page:







Notice the @Register directive at the top of the page. This is a requirement to place the controls on the page. The TagPrefix attribute is a namespace identifier for the control. The default TagPrefix is uc1 (as in User Control 1) and is changeable. The TagName attribute is the name of the control to use. The Src attribute is the location of the user control. The instance of MyControl is in the form tag. Notice that the ID is automatically created as MyControl1, the next instance will be called MyControl2, and so on.
Accessing Data from the User Control
If this user control is placed on a Web page, the TextBox and Label are visible to the user, but how can the name be retrieved? The TextBox and Label controls are declared as protected members on the Web page, which means that they are accessible only to the MyControl class and to classes that inherit from the control. To access the data for the Label and TextBox, you could expose the properties that are required, such as the Text property of the txtName TextBox and the Text property of the lblName Label. The user control is a class and can contain properties and methods. You can add properties to the user controls called UserName and UserCaption, as follows:

//C#
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class MyControl : System.Web.UI.UserControl
{
public string UserCaption
{
get { return lblName.Text; } set { lblName.Text = value; }
}
public string UserName
{ get { return txtName.Text; } set { txtName.Text = value; }
}
}

Code-Behind
//C#
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class MyControlPropertyTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
MyControl1.UserCaption = "Enter User Name:";
}
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = MyControl1.UserName;
}
}