Monday, June 29, 2015

Static Class and Static Member

Static Classes and Static Class Members (C# Programming Guide)

Visual Studio 2013
static class is basically the same as a non-static class, but there is one difference: a static class cannot be instantiated. In other words, you cannot use the new keyword to create a variable of the class type. Because there is no instance variable, you access the members of a static class by using the class name itself. For example, if you have a static class that is named UtilityClass that has a public method named MethodA, you call the method as shown in the following example:
UtilityClass.MethodA();
A static class can be used as a convenient container for sets of methods that just operate on input parameters and do not have to get or set any internal instance fields. For example, in the .NET Framework Class Library, the static System.Math class contains methods that perform mathematical operations, without any requirement to store or retrieve data that is unique to a particular instance of the Math class. That is, you apply the members of the class by specifying the class name and the method name, as shown in the following example.
double dub = -3.14;
Console.WriteLine(Math.Abs(dub));
Console.WriteLine(Math.Floor(dub));
Console.WriteLine(Math.Round(Math.Abs(dub)));

// Output:
// 3.14
// -4
// 3
As is the case with all class types, the type information for a static class is loaded by the .NET Framework common language runtime (CLR) when the program that references the class is loaded. The program cannot specify exactly when the class is loaded. However, it is guaranteed to be loaded and to have its fields initialized and its static constructor called before the class is referenced for the first time in your program. A static constructor is only called one time, and a static class remains in memory for the lifetime of the application domain in which your program resides. 
NoteNote
To create a non-static class that allows only one instance of itself to be created, see Implementing Singleton in C#.
The following list provides the main features of a static class:
  • Contains only static members.
  • Cannot be instantiated.
  • Is sealed.
  • Cannot contain Instance Constructors.
Creating a static class is therefore basically the same as creating a class that contains only static members and a private constructor. A private constructor prevents the class from being instantiated. The advantage of using a static class is that the compiler can check to make sure that no instance members are accidentally added. The compiler will guarantee that instances of this class cannot be created.
Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor; however, they can contain a static constructor. Non-static classes should also define a static constructor if the class contains static members that require non-trivial initialization. For more information, see Static Constructors (C# Programming Guide).

Example

Here is an example of a static class that contains two methods that convert temperature from Celsius to Fahrenheit and from Fahrenheit to Celsius:
    public static class TemperatureConverter
    {
        public static double CelsiusToFahrenheit(string temperatureCelsius)
        {
            // Convert argument to double for calculations. 
            double celsius = Double.Parse(temperatureCelsius);

            // Convert Celsius to Fahrenheit. 
            double fahrenheit = (celsius * 9 / 5) + 32;

            return fahrenheit;
        }

        public static double FahrenheitToCelsius(string temperatureFahrenheit)
        {
            // Convert argument to double for calculations. 
            double fahrenheit = Double.Parse(temperatureFahrenheit);

            // Convert Fahrenheit to Celsius. 
            double celsius = (fahrenheit - 32) * 5 / 9;

            return celsius;
        }
    }

    class TestTemperatureConverter
    {
        static void Main()
        {
            Console.WriteLine("Please select the convertor direction");
            Console.WriteLine("1. From Celsius to Fahrenheit.");
            Console.WriteLine("2. From Fahrenheit to Celsius.");
            Console.Write(":");

            string selection = Console.ReadLine();
            double F, C = 0;

            switch (selection)
            {
                case "1":
                    Console.Write("Please enter the Celsius temperature: ");
                    F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine());
                    Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
                    break;

                case "2":
                    Console.Write("Please enter the Fahrenheit temperature: ");
                    C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine());
                    Console.WriteLine("Temperature in Celsius: {0:F2}", C);
                    break;

                default:
                    Console.WriteLine("Please select a convertor.");
                    break;
            }

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
    /* Example Output:
        Please select the convertor direction
        1. From Celsius to Fahrenheit.
        2. From Fahrenheit to Celsius.
        :2
        Please enter the Fahrenheit temperature: 20
        Temperature in Celsius: -6.67
        Press any key to exit.
     */

Static Members

A non-static class can contain static methods, fields, properties, or events. The static member is callable on a class even when no instance of the class has been created. The static member is always accessed by the class name, not the instance name. Only one copy of a static member exists, regardless of how many instances of the class are created. Static methods and properties cannot access non-static fields and events in their containing type, and they cannot access an instance variable of any object unless it is explicitly passed in a method parameter.
It is more typical to declare a non-static class with some static members, than to declare an entire class as static. Two common uses of static fields are to keep a count of the number of objects that have been instantiated, or to store a value that must be shared among all instances.
Static methods can be overloaded but not overridden, because they belong to the class, and not to any instance of the class.
Although a field cannot be declared as static const, a const field is essentially static in its behavior. It belongs to the type, not to instances of the type. Therefore, const fields can be accessed by using the same ClassName.MemberName notation that is used for static fields. No object instance is required.
C# does not support static local variables (variables that are declared in method scope).
You declare static class members by using the static keyword before the return type of the member, as shown in the following example:
public class Automobile
{
    public static int NumberOfWheels = 4;
    public static int SizeOfGasTank
    {
        get
        {
            return 15;
        }
    }
    public static void Drive() { }
    public static event EventType RunOutOfGas;

    // Other non-static fields and properties...
}
Static members are initialized before the static member is accessed for the first time and before the static constructor, if there is one, is called. To access a static class member, use the name of the class instead of a variable name to specify the location of the member, as shown in the following example:
Automobile.Drive();
int i = Automobile.NumberOfWheels;
If your class contains static fields, provide a static constructor that initializes them when the class is loaded.
A call to a static method generates a call instruction in Microsoft intermediate language (MSIL), whereas a call to an instance method generates a callvirt instruction, which also checks for a null object references. However, most of the time the performance difference between the two is not significant.

How to : Convert ASMX 2 WCF

Convert ASMX web services to WCF


WCF provided much more features and functionality than asmx service out of the box e.g. it implements standards like WS Security, WS Addressing, WS Transaction etc. Performance wise its better than asmx services. See following links for WCF benefits:

http://msdn.microsoft.com/en-us/library/ff648122.aspx

http://msdn.microsoft.com/en-us/library/bb310550.aspx

http://msdn.microsoft.com/en-us/library/aa480190.aspx

For converting an asmx service to WCF we need to take following steps, This approach will choose appropriate serializer depending on the types defined in your asmx service.
  • Create a .wsdl file from current asmx service, you can do this by typing the service url?wsdl in IE and then save the file as .wsdl extension
  • Go to Visual Studio Command Prompt
  • Go to the directory where you saved wsdl file and run svcutil.exe with wsdl file name as argument e.g. svcutil.exe Queue.wsdl
  • The svcutil will generate two files .cs file and .config file. The .cs file will contain your service contract.



  • Create a new WCF Service Application in your solution, This template creates a service1.svc in your project, remove all files associated with Service1
  • Add a new WCF Service by using add item and name it as your own service e.g. Queue
  • Delete the interface file created in above step.
  • Copy your .cs file generated by svcutil to your WCF service application folder and include it in your project. Change the file name to indicate it as an interface e.g. IQueue.cs. You need to change the class name also and its references in the class.
  • In your generated interface file, remove , ReplyAction = “*” string for each operation, see the screen shot:




  • Implement the above interface in your implementation class
  • Build your project, and you should be good to go. 
  • You can now implement your methods by copying your old code to new one or by writing it new.
  • In order test, browse your service in browser or add a service reference to a test project, and it should generate similar interface at your end.

How to: Migrate ASP.NET Web Service Code to the Windows Communication Foundation

How to: Migrate ASP.NET Web Service Code to the Windows Communication Foundation

The following procedure describes how to migrate an ASP.NET Web Service to Windows Communication Foundation (WCF).

Procedure

To migrate ASP.NET Web service code to WCF

  1. Ensure that a comprehensive set of tests exist for the service.
  2. Generate the WSDL for the service and save a copy in the same folder as the service’s .asmx file.
  3. Upgrade the ASP.NET Web service to use .NET 2.0. First deploy the .NET Framework 2.0 to the application in IIS, and then use Visual Studio 2005 to automate the code conversion process, as documented in Step-By-Step Guide to Converting Web Projects from Visual Studio .NET 2002/2003 to Visual Studio 2005. Run the set of tests.
  4. Provide explicit values for the Namespace and Name parameters of the WebService attributes if they are not provided already. Do the same for the MessageNameparameter of the WebMethodAttribute. If explicit values are not already provided for the SOAPAction HTTP headers by which requests are routed to methods, then explicitly specify the default value of the Action parameter with a SoapDocumentMethodAttribute.
    [WebService(Namespace = "http://tempuri.org/", Name = "Adder")]
    public class Adder
    {
         [WebMethod(MessageName = "Add")]
         [SoapDocumentMethod(Action = "http://tempuri.org/Add")]
         public double Add(SumInput input)
         {
              double sum = 0.00;
              foreach (double inputValue in input.Input)
              {
                  sum += inputValue;
              }
          return sum;
         }
    }
    
  5. Test the change.
  6. Move any substantive code in the bodies of the methods of the class to a separate class that the original class is made to use.
    [WebService(Namespace = "http://tempuri.org/", Name = "Adder")]
    public class Adder
    {
         [WebMethod(MessageName = "Add")]
         [SoapDocumentMethod(Action = "http://tempuri.org/Add")]
         public double Add(SumInput input)
         {
              return new ActualAdder().Add(input);
         }
    }
    
    internal class ActualAdder
    {
         internal double Add(SumInput input)
         {
              double sum = 0.00;
              foreach (double inputValue in input.Input)
              {
                  sum += inputValue;
              }
          return sum;
         }
    }
    
  7. Test the change.
  8. Add references to WCF assemblies System.ServiceModel and System.Runtime.Serialization to the ASP.NET Web service project.
  9. Run ServiceModel Metadata Utility Tool (Svcutil.exe) to generate a WCF client class from the WSDL. Add the generated class module to the solution.
  10. The class module generated in the preceding step contains the definition of an interface.
    [System.ServiceModel.ServiceContractAttribute()]
    public interface AdderSoap
    {
         [System.ServiceModel.OperationContractAttribute(
          Action="http://tempuri.org/Add", 
          ReplyAction="http://tempuri.org/Add")]
         AddResponse Add(AddRequest request);
    }
    
    Modify the definition of the ASP.NET Web service class so that the class is defined as implementing that interface, as shown in the following sample code.
    [WebService(Namespace = "http://tempuri.org/", Name = "Adder")]
    public class Adder: AdderSoap
    {
         [WebMethod(MessageName = "Add")]
         [SoapDocumentMethod(Action = "http://tempuri.org/Add")]
         public double Add(SumInput input)
         {
              return new ActualAdder().Add(input);
         }
    
         public AddResponse Add(AddRequest request)
         {
            return new AddResponse(
            new AddResponseBody(
            this.Add(request.Body.input)));
         }
    }
    
  11. Compile the project. There may be some errors due to the code generated in step nine that duplicated some type definitions. Repair those errors, usually by deleting the pre-existing definitions of the types. Test the change.
  12. Remove the ASP.NET-specific attributes, such as the WebServiceWebMethodAttribute and SoapDocumentMethodAttribute.
    public class Adder: AdderSoap
    {
         public double Add(SumInput input)
         {
              return new ActualAdder().Add(input);
         }
    
         public AddResponse Add(AddRequest request)
         {
              return new AddResponse(
             new AddResponseBody(
            this.Add(request.Body.input)));
         }
    }
    
  13. Configure the class, which is now a WCF service type, to require WCF ASP.NET compatibility mode if the ASP.NET Web service relied on any of the following:
    • The HttpContext class.
    • The ASP.NET Profiles.
    • ACLs on .asmx files.
    • IIS authentication options.
    • ASP.NET impersonation options.
    • ASP.NET globalization.
    [System.ServiceModel.AspNetCompatibilityRequirements(
      RequirementsMode=AspNetCompatbilityRequirementsMode.Required)]
    public class Adder: AdderSoap
    
  14. Rename the original .asmx file to .asmx.old.
  15. Create a WCF service file for the service, give it the extension, .asmx, and save it into the application root in IIS.
    <%@Service Class="MyOrganization.Adder" %>
    <%@Assembly Name="MyServiceAssembly" %> 
    
  16. Add a WCF configuration for the service to its Web.config file. Configure the service to use the <basicHttpBinding>, to use the service file with the .asmx extension created in the preceding steps, and to not generate WSDL for itself, but to use the WSDL from step two. Also configure it to use ASP.NET compatibility mode if necessary.
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
     <system.web>
      <compilation>
      <buildProviders>
       <remove extension=".asmx" />
       <add extension=".asmx" 
        type=
        "System.ServiceModel.Activation.ServiceBuildProvider,
        T:System.ServiceModel, Version=2.0.0.0, 
       Culture=neutral, 
       PublicKeyToken=b77a5c561934e089" />
      </buildProviders>
      </compilation>
     </system.web>
     <system.serviceModel>
      <services>
      <service name="MyOrganization.Adder "
        behaviorConfiguration="AdderBehavior">
       <endpoint 
        address="”
        binding="basicHttpBinding"
        contract="AdderSoap "/>
       </service>
      </services>
      <behaviors>
      <behavior name="AdderBehavior">
       <metadataPublishing 
        enableMetadataExchange="true" 
        enableGetWsdl="true" 
        enableHelpPage="true" 
        metadataLocation=
        "http://MyHost.com/AdderService/Service.WSDL"/>
      </behavior>
      </behaviors>
      <serviceHostingEnvironment 
       aspNetCompatibilityEnabled ="true"/>
     </system.serviceModel>
    </configuration>
    
    
  17. Save the configuration.
  18. Compile the project.
  19. Run the set of tests to make sure all the changes work.

Wednesday, June 10, 2015

SQL 2008 Query Optimization

Problem
Have you ever come across a situation where a query will perform well most of the time, but as soon as you change the predicate value, the same query is 10 to 30 times slower?
Solution
In my opinion, one of the goals of writing tips for  share valuable information with the community. Not long ago, I came across a valuable webcast about query tuning and optimization. I found it so useful that I decided to share a little bit of it in this tip.
All the examples below have been taken with the permission of the author from www.sqlworkshops.com and in order to make it work you must run on this on SQL Server 2008 64bit edition.
Lets create our sample table:
create table tab7 (c1 int primary key clustered, c2 int, c3 char(2000)) 
go
begin tran
go
declare @i int
set @i = 1
while @i <= 200000
begin
insert into tab7 values (@i, rand() * 200000, replicate('a', 2000))
set @i = @i + 1
end
commit tran
go
Lets update the statistic with a full scan to make the optimizer work easier:
update statistics tab7 with fullscan
go
Let's set statistics time on and execute the following query:
set statistics time on
go
 
declare @c1 int, @c2 int, @c3 char(2000)
select @c1 = c1, @c2 = c2, @c3 = c3
from tab7
where c1 < 3057 -- 3057
order by c2
The is the time it took to run on my machine: CPU time = 16ms, elapsed time = 15ms
The query ran fine. It only took 15ms (milliseconds) of elapsed time. If we check the actual execution plan we can see that 90% of the cost is spent on the clustered index seek.

Let's change the predicate value to 3058 and run the same query again.
declare @c1 int, @c2 int, @c3 char(2000)
select @c1 = c1, @c2 = c2, @c3 = c3
from tab7
where c1 < 3058 -- 3058
order by c2
The is the time it took to run on my machine: CPU time = 16ms, elapsed time = 207ms
Wow, the query now takes 207ms of elapsed time. The query with predicate 3058 is now 13 times slower than the same one with predicate 3057. Why?  If we take a look at the new execution plan, we can see that it has not changed. The optimizer is using the same plan for both queries.

Someone may think that adding an index on c1 would speed up our query, but the answer is no, because c1 is not using an equal (=) predicate but a range predicate (<).
So, why is the second query much slower?
Let's take a look at tempDB activity.  Let's run the following query and take note of the results. (Note: I have only 1 tempDB file on my computer)
select num_of_reads, num_of_bytes_read,
num_of_writes, num_of_bytes_written
from sys.dm_io_virtual_file_stats(db_id('tempdb'), 1)
This is the output:
num_of_reads = 5643 num_of_bytes_read =361488384 
num_of_writes 5434 num_of_bytes_written =353394688
Let's run the second query again:
declare @c1 int, @c2 int, @c3 char(2000)
select @c1 = c1, @c2 = c2, @c3 = c3
from tab7
where c1 < 3058 -- 3058
order by c2
and monitor tempDB again:
select num_of_reads, num_of_bytes_read,
num_of_writes, num_of_bytes_written
from sys.dm_io_virtual_file_stats(db_id('tempdb'), 1)
This is the output:
num_of_reads =5740 num_of_bytes_read =367755264 
num_of_writes =5530 num_of_bytes_written =359661568
When the query runs with predicate 3057 there is no activity on tempDB, but when it runs with predicate 3058 we can see tempDB activity.
Lets do another test.
Lets start SQL Server Profiler and monitor "Sort Warnings". If we run the query with predicate 3057 we do not see any Sort Warnings however, we can see they exist if we run the query with predicate 3058.
We can now conclude that the query with a predicate greater and equal to 3058 is slower than the one with predicate equal to or less than 3057, because SQL Server executes the sort operation in tempDB and not in memory.

Of course, if we eliminate the order by clause, the query will perform well, however our goal is to make the query  perform well in spite the order by clause.

Let's run the following query in a loop and take note of the SPID number. In my case it is 60.
while 1=1
begin
declare @c1 int, @c2 int, @c3 char(2000)
select @c1 = c1, @c2 = c2, @c3 = c3
from tab7
where c1 < 3057 -- 3057
order by c2
end
In another query window let's run the following:
select granted_memory_kb, used_memory_kb, max_used_memory_kb
from sys.dm_exec_query_memory_grants
where session_id = 60 
We can see that the above query was granted 8176KB of memory and used only 5248KB. Enough memory was granted by SQL to execute the sort operation in memory.
Now, lets repeat the above steps using the same query with predicate 3058
while 1=1
begin
declare @c1 int, @c2 int, @c3 char(2000)
select @c1 = c1, @c2 = c2, @c3 = c3
from tab7
where c1 < 3058 
order by c2
end
In another query window let's run the following :
select granted_memory_kb, used_memory_kb, max_used_memory_kb
from sys.dm_exec_query_memory_grants
where session_id = 60 
Now, we can see that the query used all the granted memory and because it was not enough to successfully execute the sort operation in memory, SQL had to use tempDB to complete the sort.
To make the query run consistently fast in spite of the sort operation, we need to trick SQL and let it allocate more memory for our query, but how do we do it?
Simply by increasing the estimated row size, SQL will allocate more memory to the query allowing it to execute the sort in memory.
Let's rewrite the query as follows:
declare @c1 int, @c2 int, @c3 varchar(4500)
select @c1 = c1, @c2 = c2, @c3 = convert(varchar(4500),c3)
from tab7
where c1 < 3058
Now, let's include the execution plan and run it.

Much to our surprise, we can see that the introduction of a compute scalar has made SQL think that the estimated row size is 2269 and therefore it allocated more memory to the query allowing the sort operation to be executed in memo

'Migration From Asp.Net 2.0 to Higher Version

Migration Procedure


Introduction
I would like to share the procedure for migrating applications to .Net 4.5 from .Net 2.0/3.0/3.5. I used various web resources to collect the following information and tried to summarize it so it is easy to understand.

So let’s start with the problem statement.

Problem Statement 
We have an application developed in .Net 2.0/3.0 and we are using .Net 4.5 to run this application. What will happen?

Answer: It shows error

By default, an app runs on the version of the .Net Framework that it was built for. If that version is not present and the app configuration file does not define supported versions then a .Net Framework initialization error may occur. In this case, the attempt to run the app will fail.

Explanation

It depends upon the CLR for the .Net framework we are using.
  1. .Net Framework 2.0, 3.0, and 3.5 include CLR 2.0
  2. .Net Framework 4, 4.5, and 4.5.1 include CLR 4.0
  3. CLR 3.0 does not exist
  4. An application developed in .Net 2.0 or 3.0 can run in a 3.5 framework because the target CLR is the same
But an application developed in .Net 3.0 will not run in a 4.5 framework because now the target framework is different (CLR 4)

Solution

To configure your application to run on .Net Framework 4 or 4.5:
  1. Create a text file that has the same name as your application, and add the file extension .config. For example, if your application is named abc.exe then your application configuration file must be named abc.exe.config.
  2. Add the <supportedRuntime> element as follows to the application configuration file:
    <configuration>
      <startup>
        <supportedRuntime version="version"/>

      </startup>

    </
    configuration> 

    • .Net Framework 1.0: "v1.0.3705"
    • .Net Framework 1.1: "v1.1.4322"
    • .Net Framework 2.0, 3.0, and 3.5: "v2.0.50727"
    • .Net Framework 4 and 4.5 (including point releases such as 4.5.1): "v4.0"
Something about Backward compatibility
Backward compatibility means that an app that was developed for a specific version of a platform will run on later versions of that platform. The .Net Framework tries to maximize backward compatibility: Source code written for one version of the .Net Framework should compile on later versions of the .Net Framework, and binaries that run on one version of the .Net Framework should behave identically on later versions of the .Net Framework

The .Net Framework 4.5 and its point releases are backward-compatible with apps that were built with earlier versions of the .Net Framework. In other words, apps and components built with previous versions will work without modification on the .Net Framework 4.5. However, by default, apps run on the version of the Common Language Runtime for which they were developed, so you may need to provide a configuration file to enable your app to run on the .Net Framework 4.5. For more information
  • Note that the .Net Framework 4.5 is not supported on Windows XP.
  • .Net 4.5 comes automatically with Windows 8
  • .Net 3.5 sp1 comes automatically with Windows 7 sp1





How to: Upgrade an ASP.NET Web Application to ASP.NET 4

If you use Visual Studio to open a Web project that was developed for the .NET Framework 2.0, the .NET Framework 3.0, or the .NET Framework 3.5, Visual Studio can automatically perform all the changes to Web.config files that are required to be able to run using .NET Framework version 4. If the project is a local IIS project and you are using IIS 7.0, Visual Studio can also reassign the application to an application pool that is associated with the .NET Framework version 4.
It is recommended that you use Visual Studio to perform the tasks that are required in order to upgrade. If you do not use Visual Studio to perform the upgrade automatically, you must manually edit the Web.config file and must manually associate the application in IIS with the .NET Framework version 4. 
Typically the procedures covered in this topic are sufficient for upgrading a Web application, because later versions of the .NET Framework are designed to be backward compatible with earlier versions. However, you should also look in the readme documentation for breaking changes. The behavior of a component that was developed for an earlier version of the .NET Framework might have changed in the newer version of the .NET Framework.

To upgrade an application by using Visual Studio

  1. Open the Web site or project in Visual Studio.
  2. If a Visual Studio Conversion Wizard welcome dialog box appears, click Next.
    This wizard appears when you open a Web Application Project or a solution. It does not appear when you open a Web Site project that is not in a solution.
    Visual Studio Conversion Wizard dialog box
  3. If you are converting a project, in the Visual Studio Conversion Wizard, select backup options and click Next in the Choose Whether to Create a Backup dialog box.
    Visual Studio Conversion Wizard backup dialog box
    Visual Studio upgrades your project file to the Visual Studio 2010 format. If you are upgrading a solution instead of an individual project, Visual Studio upgrades the solution file to the Visual Studio 2010 format.
  4. If you are converting a project, in the Visual Studio Conversion Wizard, click Next in the Ready to Convert dialog box.
    Visual Studio Conversion Wizard Ready dialog box
  5. If you are opening the Web project on a computer that does not have the .NET Framework 3.5 installed, in the Project Target Framework Not Installed dialog box, select Retarget the project to .NET Framework 4 and click OK.
    Project Target Framework Not Installed dialog box
  6. If you are opening the Web project on a computer that does have the .NET Framework 3.5 installed, in the Web Site targeting older .NET Framework Found dialog box, clear the check box if you do not want to upgrade all Web sites or projects in a solution.
    .NET Framework version selection Dialog Box
  7. In the dialog box, click Yes.
    Visual Studio updates the Web.config file. The changes that are made to the Web.config file are listed in the procedure later in this topic that explains how to update the Web.config file manually. Visual Studio does not update comments. Therefore, after the conversion, the Web.config file might contain comments that reference earlier versions of the .NET Framework. 
    Visual Studio automatically sets the controlRenderingCompatibilityVersion attribute of the pages element to 3.5. You can remove this setting in order to take advantage of XHTML and accessibility improvements in ASP.NET 4. For more information, see the procedure later in this topic that explains how to update the Web.config file manually.
  8. If you are converting a project, in the Visual Studio Conversion Wizard, click Close in the Conversion Complete dialog box.
    Visual Studio Conversion Wizard Close dialog box
  9. If the project is not a local IIS project, associate its IIS application with the Visual Studio when it is deployed to IIS. For more information, see the procedure later in this topic that corresponds to the version of IIS that you are using.
    If the IIS application is associated with the .NET Framework 2.0, the site will not work. ASP.NET will generate errors that indicate that the targetFramework attribute is unrecognized.
  10. If the project is a local IIS project and the IIS version is 6.0, associate its IIS application with the Visual Studio by following the procedure later in this topic for IIS 6.0. 
    If the project is a local IIS project, Visual Studio automatically performs this association. It assigns the application to the first available application pool for the .NET Framework version 4. If no application pool exists, Visual Studio creates one.

    Turn Windows Features On or Off dialog box
  11. If the project includes code that accesses the HttpBrowserCapabilities object (in the HttpRequest.Browser property), test the code to make sure that it works as expected.
    The browser definition files that provide information to the HttpBrowserCapabilities object were changed in ASP.NET 4, and the changes are not backward compatible with earlier versions of ASP.NET. If you discover a problem and prefer not to change your code to accommodate the ASP.NET 4 changes, you can copy the ASP.NET 3.5 browser definition files from the ASP.NET 3.5 Browsers folder of a computer that has ASP.NET 3.5 installed to the ASP.NET 4 Browsers folder. The Browsers folder for a version of ASP.NET can be found in the following location:
    %SystemRoot%\Microsoft.NET\Framework\versionNumber\Config\Browsers
    After you copy the browser definition files, you must run the aspnet_regbrowsers.exe tool. For more information, see ASP.NET Web Server Controls and Browser Capabilities.

To manually upgrade an application's Web.config file from the .NET Framework 3.5 to the .NET Framework 4

  1. Make sure that the application currently targets ASP.NET 3.5.
    Open the Web.config file in the application root.
  2. In the configSections section, remove the sectionGroup element that is named "system.web.extensions".
  3. In the system.web section, in the compilation collection, remove every add element that refers to an assembly of the .NET Framework.
    Framework assemblies generally begin with "System.". Typically these have Version=3.5.0.0 in the assembly attribute. However, some assembly entries that have the 3.5.0.0 version number might refer to assemblies that were installed as part of add-on releases, or to custom assemblies. Do not delete these. If the Web.config file contains any of these references, you must investigate them individually to determine whether a later version is available and whether the version reference must be changed.
  4. Add a targetFramework attribute to the compilation element in the system.web section, as shown in the following example:
    <compilation targetFramework="4.0">
    
    In the opening tag for the pages section, add a controlRenderingCompatibility attribute, as shown in the following example:
    <pages controlRenderingCompatibilityVersion="3.5"/>
    
    Many ASP.NET 4 controls render HTML that is compliant with XHTML and accessibility standards. However, the Web site that you are converting might have CSS rules or client script that will not work correctly if Web pages change the way they render HTML. If you want to take advantage of the control rendering enhancements in ASP.NET 4, you can omit this attribute. For more information, see ControlRenderingCompatibilityVersion.
  5. In the system.codedom section, in the compilers collection, remove the compiler elements for c# and vb.
  6. Delete everything between the system.webserver section start and end tags, but leave the tags themselves.
  7. Delete everything between the runtime section start and end tags, but leave the tags themselves.
  8. If you have customized the Web.config file, and if any customizations refer to custom assemblies or classes, make sure that the assemblies or classes are compatible with the .NET Framework version 4.
    The following example shows an example Web.config file for a simple Web application that was converted from the .NET Framework version 3.5 to the .NET Framework version 4.
    <?xml version="1.0"?>
    <!-- 
        Note: As an alternative to hand editing this file you can use the 
        web admin tool to configure settings for your application. Use
        the Website->Asp.Net Configuration option in Visual Studio.
        A full list of settings and comments can be found in 
        machine.config.comments usually located in 
        \Windows\Microsoft.Net\Framework\v2.x\Config 
    -->
    <configuration>
      <appSettings/>
      <connectionStrings>
        <add name="NorthwindConnection" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\NORTHWND.MDF;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient"/>
      </connectionStrings>
      <system.web>
    <!-- 
        Set compilation debug="true" to insert debugging 
        symbols into the compiled page. Because this 
        affects performance, set this value to true only 
        during development.
    -->
      <compilation debug="true" targetFramework="4.0">
        <assemblies>
        </assemblies>
      </compilation>
    <!--
        The <authentication> section enables configuration 
        of the security authentication mode used by 
        ASP.NET to identify an incoming user. 
    -->
      <authentication mode="Windows"/>
    <!--
        The <customErrors> section enables configuration 
        of what to do if/when an unhandled error occurs 
        during the execution of a request. Specifically, 
        it enables developers to configure html error pages 
        to be displayed in place of a error stack trace.
            <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
                <error statusCode="403" redirect="NoAccess.htm" />
                <error statusCode="404" redirect="FileNotFound.htm" />
            </customErrors>
    -->
      <pages controlRenderingCompatibilityVersion="3.5"/></system.web>
      <system.codedom>
      </system.codedom>
    <!-- 
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.
    -->
      <system.webServer>
      </system.webServer>
    </configuration>
    

To associate an IIS application with the .NET Framework 4 in IIS 7.0

  1. In Windows, start Inetmgr.
  2. In the Connections pane, expand the server node and then click Application Pools.
  3. On the Application Pools page, select the application pool that contains the application that you want to change.
  4. In the Actions pane, click View Applications.
  5. Select the application whose application pool that you want to change and then click Change Application Pool in the Actions pane.
  6. In the Select Application Pool dialog box, select an application pool that is associated with .NET Framework version 4 from the Application pool list, and then click OK.

To associate an IIS application with the .NET Framework 4 in IIS 6.0