Common Web Project Conversion Issues and Solutions

 

Michael Bundschuh
Program Manager, Microsoft
Robert McGovern
Infusion Development

November 2005 (Updated for the Visual Studio 2005 RTM release)

Applies to:
   ASP.NET 1.x
   ASP.NET 2.0
   Visual Studio .NET 2003
   Visual Studio 2005

Summary: Reviews both Visual Studio 2005 Web project and ASP.NET 2.0 framework changes that affect Web project conversion, and then discusses common issues and solutions for converting using Visual Studio 2005. (31 printed pages)

Contents

Part 1: Web Project Changes
   What Is ASP.NET and Visual Studio?
   Web Project Changes
   New Features
   Converting a Web Project
   The Conversion Wizard
   The Conversion Report
Part 2: Common Conversion Issues
   Issue 1: Code-behind class file (CB-CB) references
   Issue 2: Stand-alone class file (SA–CB) references
   Issue 3: Circular references
   Issue 4: Resource Manager
   Issue 5: Excluded files are no longer excluded
   Issue 6: Orphaned resx files
   Issue 7: Extra types in a code-behind file
   Issue 8: Accessing an auto-generated control variable
   Issue 9: Unable to switch to design view
   Issue 10: Unable to parse filename
Part 3: Other Conversion Issues
   Issue 11: Backup folder in the Web project folder
   Issue 12: Multiple projects in the same location
   Issue 13: Multiple projects referring to the same files
   Issue 14: Invalid access modifier
   Issue 15: Converting excluded files
   Issue 16: Duplicate variable declarations
   Issue 17: Sub-Web applications
   Issue 18: OnInit() not removed
   Issue 19: XHTML validation errors
   Issue 20: Multiple configurations
   Issue 21: Auto-generated members hide inherited members
   Issue 22: Ambiguous references and naming conflicts
   Issue 23: Event handlers called multiple times
   Issue 24: Code-behind files moved to the App_Code folder
   Issue 25: Projects referencing a Web project
   Issue 26: Sharing the same code-behind file
   Issue 27: Partially converted solutions
   Issue 28: No command-line migration for C#
   Issue 29: Batch = True or False
Summary
Appendix A: Actual Error Messages

Part 1: Web Project Changes

As you convert your Visual Studio 2002/2003 Web projects to Visual Studio 2005, you may encounter issues with the changes made in the Web project system. In this article, we will look at both the conversion process and some of the common issues you may encounter during a conversion.

What Is ASP.NET and Visual Studio?

ASP.NET is a technology for creating dynamic Web applications. ASP.NET pages (Web Forms) are compiled and allow you to build powerful forms-based Web pages. When building these pages, you can use ASP.NET user controls to create common UI elements and program them for common tasks.

Visual Studio is an integrated development environment (IDE) that developers can use to create programs in one of many languages, including C# and Visual Basic, for the .NET Framework.

You will find that converting your Web application to use the new Visual Studio 2005 and ASP.NET 2.0 features both simplifies your development and gives you more options for compiling and deploying your code.

Web Project Changes

These changes affect how you develop, configure, and deploy your Web applications. As either a developer or a Web site administrator, you will need to be aware of these changes in order to properly build, deploy, and maintain your Web applications.

  • No project file. Visual Studio 2005 no longer uses a project file to explicitly list the files in your Web project. Instead, it considers all files and folders to be part of the Web project. Project information that was stored in the project file is now stored in the solution or Web.config file.
  • Special directories. An ASP.NET 1.x application has one required folder (\bin) for containing assemblies. An ASP.NET 2.0 application has a larger defined folder structure. The new directories start with the prefix "App_" and are designed for storing resources, assemblies, source code, and other components. The new folder structure helps eliminate the need for a project file and also enables some new options for deployment.
  • Code-behind model. In ASP.NET 1.x, the code-behind model allows separation of content (e.g. foo.aspx) from code (e.g. foo.aspx.vb). The content page inherits from the code-behind page and the code-behind page contains both user and designer generated code.
    ASP.NET 2.0 enhances the code-behind model with partial classes, which allows a class to span multiple files. In the new code-behind model, the content page inherits from a compiled class consisting of its corresponding code-behind page plus an auto-generated partial class that defines the field declarations for the controls used in the content page. This change allows the auto-generated code to be separated from the user's code, and makes the code-behind page much smaller and cleaner. The partial class structure also reduces the risk of inadvertently breaking the page by editing designer generated code.
  • Compilation model (one assembly to many assemblies). In Visual Studio .NET 2003 all the code-behind class files, and support code are precompiled into a single assembly with a fixed name. In Visual Studio 2005, multiple assemblies are created on the fly (by default) with uniquely generated filenames. For example, the default behavior is to compile all Web forms and user controls in a folder into its own assembly. The common source code in the App_Code folder will automatically be compiled into its own separate assembly. This new compilation model causes some changes in the structure of a Web application, but greatly enhances the options for deployment and how the Web application is served on the Web server.
  • Deployment options (precompile, full compile, updateable sites, etc). In prior versions of Visual Studio, Web applications are precompiled and deployed as one large assembly. Content pages (e.g. *.aspx or *.ascx) are not compiled and editable on the server. Thanks to the new page compilation model and folder structure in Visual Studio 2005, you can deploy a Web application in many different configurations. At one extreme, you can precompile all the content pages, their code-behind class files and its hidden designer page and deploy a Web application that consists of fully compiled assemblies. In this mode, your application cannot easily be changed on the server. At the other extreme, you can deploy an application with no precompiled code at all. In this configuration, you can change the content pages, code-behind class files, or any other code in the application on the server directly. The pages will be dynamically compiled when a user asks for the page from the server.

Each of these operational changes may require you to modify your application architecture and deployment process either before or after converting your Web application.

New Features

Converting your Web application will make your application more powerful, flexible, and maintainable. Although this article focuses on the mechanics of converting your application, you can learn more about the new Visual Studio 2005 and ASP.NET 2.0 features through the following links:

  • Feature Overview
    This white paper will give you a good overview of the new features available with ASP.NET 2.0. If you are looking at leveraging ASP.NET 2.0 content on a site built with ASP.NET 1.x, you should read through this paper to see what is available for you.
  • Personalization
    ASP.NET 2.0's personalization features, called Web Parts, let you design your Web site to be reactive to individual users. You can, for instance, let each user pick a site layout or color scheme and have that information preserved between visits. Web Parts allows you to provide personalization features with a minimal amount of new code.
  • Data Access
    Not only has ADO.NET been updated for the .NET Framework 2.0, but ASP.NET 2.0 also now includes a new set of data source controls and features for data access.
  • Master Pages
    In traditional ASP.NET, most developers struggle with designing a Web application framework that combines code reuse with flexibility. Master pages give the best of both worlds by introducing true inheritance. You can set up a master page that contains your header, footer, and navigation bar, and then create child pages that fill in the content while automatically inheriting the look, behaviors, and features of the master page.
  • ASP.NET Development Server
    A stand-alone, development-only Web server is now bundled with Visual Studio 2005. This server, code-named "Cassini," allows users to develop and test their Web applications without having to have IIS installed on their development system. This server can be used only for development. When you deploy your application to production, you will need to use an IIS server configured with ASP.NET 2.0.

Converting a Web Project

Converting a Web Project involves more than just changing your framework version! There are three parts to a conversion:

  1. Before Conversion – reviewing and possibly altering your Web project architecture before running the conversion wizard.
  2. Conversion – running the Visual Studio 2005 conversion wizard to convert your Web project.
  3. Post Conversion – resolving any issues the conversion wizard did not catch or was unable to resolve.

For parts 1 and 2, you should read and apply the steps outlined in Step-By-Step Guide to Converting Web Projects to Visual Studio .NET 2005.

For part 3, you should apply the solutions outlined in this white paper.

The Conversion Wizard

Visual Studio 2005 has a built-in conversion wizard to help you convert your Web applications. This wizard automates many of the basic steps necessary to convert your application to use ASP.NET 2.0 features.

Running the Wizard

The conversion wizard is automatically invoked whenever you open a Visual Studio .NET 2003 Web project in Visual Studio 2005. The wizard detects the presence of a Web project file (e.g. *.vbproj or *.csproj) in the application folder and automatically starts the conversion process.

Aa479312.upgradingaspnet01(en-us,MSDN.10).gif

Figure 1. The Conversion Wizard

The first choice you have to make is to create a backup of your application before conversion. It is highly recommended you make a backup!

Aa479312.upgradingaspnet02(en-us,MSDN.10).gif

Figure 2. Backup your application

If you choose to create a backup, Visual Studio 2005 will automatically create a copy of your Web project in the folder of your choice.

Note   Make sure you put the backup folder outside of your Web application's folder tree. See the Backup folder in the Web application folder issue for full details.

Next, you will see a summary screen of the conversion process and have one last opportunity to back out of the conversion. Please note two things about this summary screen:

Note   The first paragraph is incorrect since it states a Web project will be checked out from source code control before changes are made. This is true for Visual Basic and C# client projects, but not Web projects. Instead, the Web project conversion wizard will ignore source code control and change files it must modify to read-write.

The Web project will be converted in-place, which is why making a backup is both recommended and important.

Aa479312.upgradingaspnet03(en-us,MSDN.10).gif

Figure 3. Summary screen

The conversion may take a few minutes, depending on the size of your application. When it completes you will see a message indicating your Web project was converted. You may also see a message about some warnings or errors. Warnings and errors occur when the conversion wizard has made changes that may modify the behavior of your application, or when it can't completely update your Web project.

Aa479312.upgradingaspnet04(en-us,MSDN.10).gif

Figure 4. Conversion completed

After the conversion is complete, you are ready to look at the conversion report to see if you have to perform any additional manual steps to complete your conversion.

The Conversion Report

The conversion wizard will record the changes it makes to your Web project in both an XML and a text file. When the conversion wizard finishes it displays the XML version of the report. This report will show you any issues encountered by the wizard and code areas where you may need to take additional steps to complete the conversion.

The report is divided into sections for the converted solution and one or more projects. The solution report will almost always be error free. However, the project sections may have multiple issues listed for each file in your project. You should review this section and resolve any issues reported by the conversion wizard.

Click here for larger image

Figure 5. Conversion report (click for larger image)

If you close the conversion report, you can always find a text version at the top level of your converted project.

Note   In the final release of Visual Studio 2005, the name of the text report is ConversionReport.txt. Future releases will rename this file to ConversionReport.webinfo. The text version will be found in the Web application's root folder.

Notification Types

Each item in the report falls into one of three categories:

  • Comments—informs you of actions taken by the wizard. You will see many comments about files that were deleted or moved, and code that was deleted or commented out. Comments are listed in the text version, but omitted in the XML version, of the conversion report.
  • Warnings—A warning is generated whenever the wizard has to take an action that may cause a behavioral change or possible compilation error in your application. Warnings are items you want to review, but may not need to act on.
  • Errors—An error item is generated if the wizard encounters something that it cannot automatically convert. These items require your effort to complete the conversion. Generally, an error is something that will generate a compilation error if you try to run the application.

Part 2: Common Conversion Issues

Although Visual Studio 2005 is designed to work with code developed using Visual Studio .NET 2003, you may encounter one or more common conversion issues. In this section, we will look at several of the most common issues.

Note   The conversion wizard has been upgraded in the final release of Visual Studio 2005, and may automatically detect and fix some of the following issues. However, if the wizard misses a particular issue, the solutions described below can be applied manually to finish converting your Web project.

Issue 1: Code-behind class file (CB-CB) references

Note CB is an acronym for the code-behind file for either a Web form (*.aspx) or a user control (*.ascx).

The new compilation model uses multiple assemblies that are normally dynamically compiled on the server. This model improves both Web site performance and updatability.

However, if your code-behind files reference another code-behind file, then you will have a broken reference because the referenced code-behind file will no longer be in the same assembly.

Here are some common ways it may be triggered:

  • Using a Web form or user control as a base class to another Web form or user control.
  • Using LoadControl() and casting the result to another user control, for example
    UserControl1 c1 = (UserControl1)LoadControl("~/UserControl1.ascx");
  • Creating an instance of the Web form class, for example
    WebForm1 w1 = new WebForm1();
    where WebForm1 is a class defined in a code-behind file for a Web form.

How to fix

To resolve the problem, you will need to change your application so the reference can be found. Since this is a CB-CB reference, the easiest way to resolve is to add a reference directive to the Web form or user control that is making the reference. This will tell the compiler what assembly to link to.

Let's assume you have the following situation:

File ASP.NET 1.x Code
Page1.ascx  
Page1.ascx.cs
Control1 c = (Control1)LoadControl("~/Control1.ascx");

Change your code to use a reference directive:

File ASP.NET 2.0 Code
Page1.ascx
<%@ Reference Control="~/Control1.ascx" %>
Page1.ascx.cs
Control1 c = (Control1)LoadControl("~/Control1.ascx");

By using the reference directive, you are explicitly telling the compiler where to look for the Web form or control you want to use. Note that in the final release of Visual Studio 2005 the conversion wizard will do this automatically for you.

Issue 2: Stand-alone class file (SA–CB) references

Note SA is an acronym for a stand-alone class file.

You may encounter another type of broken reference if you have a stand-alone class file that references code in a code-behind class file. This is similar to a CB-CB broken reference, except you have a stand-alone class file in the App_Code folder trying to reference a separate page assembly. A common way it can be triggered is by accessing a class variable in the CB class.

How to fix

Fixing an SA-CB broken reference is more involved. Since the problem occurs in an SA file, you cannot use a reference directive to find the reference. Also, after conversion, the SA file is moved to the App_Code folder so the class file will only have access to the App_Code assembly where it is compiled.

The solution is to create an abstract base class in the App_Code folder to reference at compile time, which will load the actual class from the page assembly at run time.

Let's assume you have the following situation:

File ASP.NET 1.x Code
Control1.ascx
inherits="Control1"
Control1.ascx.cs
class Control1 : System.Web.UI.UserControl { 
    public static string myName = "Control1";
    public void foo() { some code } 
}
Code1.cs
String myName = "Class1 + " + Control1.myName;

Change your code to use an abstract base class:

File ASP.NET 2.0 Code
Control1.ascx
inherits="migrated_Control1"
Control1.ascx.cs
class migrated_Control1 : Control1 { 
    override public void foo() { some code } 
}
App_Code\Code1.cs
String myName = "Class1 + " + Control1.myName;
App_Code\Stub_Control1.cs
abstract class Control1 : System.Web.UI.UserControl {
    public static string myName = "Control1";
    abstract public void foo(); 
}

The abstract base class will allow both standalone class files and CB files to find a class during compilation (named Control1 in this example) since it now exists in the App_Code folder. However, the standalone class file will use late-binding to load the original class (renamed to migrated_control in this example) during runtime. Note: in the final release of Visual Studio 2005, the conversion wizard will create this code for you automatically.

Issue 3: Circular references

A circular reference happens when a code-behind file references another code-behind

file, which in turn references the original file. It can happen with two or more code-behind files, e.g.:

Aa479312.circular-ref1(en-us,MSDN.10).gif

It can also happen between assemblies, where one assembly references another

assembly, which in turn references the original assembly, e.g.:

Aa479312.circular-ref2(en-us,MSDN.10).gif

How to fix

The solution for first type of circular reference is to create an abstract base class in the App_Code folder with one of the references, then remove the Reference directive from the associated Web form or user control file. This will break the circular reference.

The second type of circular reference is a by-product of the ASP.NET compiler "batching" assemblies together for performance reasons. By default it will take the Web forms and user controls in a folder and compile them into an assembly.

There are several ways to solve this issue, but we recommend moving the referenced pages (e.g. Pages2.aspx.vb and Pages3.aspx.vb) to their own folder. By

default, the ASP.NET compiler will create a separate assembly containing these pages and the circular reference will be removed between Assembly A and B.

Aa479312.circular-ref3(en-us,MSDN.10).gif

Issue 4: Resource Manager

In Visual Studio .NET 2003, a resource manager is used to manage resources in your Web application. A typical example would look like the following:

File ASP.NET 1.x Code
Control1.ascx.cs
Assembly a = Assembly.Load("myApp");
ResourceManager rm = new ResourceManager("myApp.Resource1", a);
String s = rm.GetString("foo");
Resource1.resx
Contains name/value pair  "foo = bar"

This type of code is problematic since it depends on you knowing the name of the assembly to load, which is no longer a fixed name in Visual Studio 2005.

How to fix

Since Visual Studio 2005 uses non-deterministic assembly naming, you will need to change your code to use the new resource model. The easiest way is to move Resource1.resx to a special folder named App_GlobalResources. Visual Studio 2005 will automatically make any resources found in this folder available via strong naming (and discoverable using IntelliSense) to your Web application. Here is the converted example:

File ASP.NET 2.0 Code
Control1.ascx.cs
String s = Resources.Resource1.foo;
App_GlobalResources\
Resource1.resx
Resource1.resx moved to App_GlobalResources
Contains name/value pair  "foo = bar"

This is just one way to use the new resource model in Visual Studio 2005—you should review the resource model documentation to discover the new capabilities in this model.

Issue 5: Excluded files are no longer excluded

In Visual Studio .NET 2003, you had to explicitly decide whether or not to include files in your Web project. If a file was not explicitly listed as included, then the file was excluded from the project. You could also stop a code file from being built by setting its build action to "none". This information is stored in the project file.

When converting, several issues have to be considered, e.g.:

  • A file that is excluded from one project may be included in another project
  • Should you try to convert an excluded file, since it may just be a code snippet the user wants to remember?

In the final release of Visual Studio 2005, the conversion wizard will leave excluded files as-is and note them in the conversion report. As a result, your Web project will contain extra, unconverted files that are now part of your project. Depending on the file's extension, the compiler may try to compile the file, which may cause conflicts in your application.

How to fix

After conversion, you can delete any formerly excluded files you do not want from your project. You can also use the "Exclude from Project" feature (found on the Solution Explorer menu) to exclude them by renaming them with the safe extension ".exclude" to effectively remove them from your Web application.

Note   files excluded with the ".exclude" extension are still part of the Web project but they will not be compiled, nor will these files be served by IIS/ASP.NET if they happen to be on the server.

Note   future releases of the conversion wizard will be more proactive and exclude files when it is considered safe to do so.

Issue 6: Orphaned resx files

Visual Studio .NET 2003 generated a resx (resource) file for Web forms and user controls. In general, users did not use them since they were auto-generated and could potentially overwrite user-added code.

After conversion, these resx files are not deleted since the migration wizard is not sure if the user has added resources that need to be saved.

How to fix

Review the generated resx files and save user data to its own resource file. It is fine to combine this data into one resource file.

Move the resource file to the special folders App_GlobalResources or App_LocalResources as appropriate so it is available to your Web application.

After saving the user data in this way, delete the generated resx files from your Web project.

Aa479312.issue-orphaned-resx(en-us,MSDN.10).gif

Issue 7: Extra types in a code-behind file

In Visual Studio .NET 2003, it was possible to share types (e.g. structs, enums, interfaces, modules, etc.) across different pages by storing the types in a code-behind file for one of the Web forms or user controls.

This model breaks in Visual Studio 2005 since a Web form and user controls are compiled into their own assemblies—the extra types will no longer be discoverable.

How to fix

After the conversion wizard has converted your application, just move any non-private extra type to its own standalone code file in the App_Code folder. You will also need to change the access modifier for the type to public since it has to work across assemblies. The shared type will automatically be compiled and discoverable throughout your Web application.

Issue 8: Accessing an auto-generated control variable

In Visual Studio .NET 2003, the code-behind class file contained both user and auto-generated designer code. The latter could contain both control variable declarations and page functions. Although it is not recommended, some developers changed the access permission of the control variables to Public so they could be modified from outside their class. An example looks like this:

File ASP.NET 1.x Code
UserCtrl1.ascx
<asp:Label id="Label1" runat="server">UC1</asp:Label>
UserCtrl1.ascx.cs
public System.Web.UI.WebControls.Label Label1;
Page1.ascx.cs
UserCtrl1 uc1 = (UserCtrl1)LoadControl("~/UserCtrl1.ascx");
uc1.Label1.Text = "Foo";

In Visual Studio 2005, this change will not work since the user and auto-generated designer code is separated using a partial class. A partial class allows a class to span more than one file, and is used to maintain a clean separation between user and auto-generated code.

How to fix

In general, it is recommended you change your code to not depend on the changed access level of auto-generated code. However, there is a workaround that is useful if you have hundreds of places in your code calling such auto-generated control variables, and you need to quickly get your code running. You can rename the original control variable to something else, then create a public property to access your renamed control variable. For example:

File ASP.NET 2.0 Code
UserCtrl1.ascx
<asp:Label id="p_Label1" runat="server">UC1</asp:Label>
UserCtrl1 hidden partial class
// this will be auto-generated in the hidden, partial class
protected System.Web.UI.WebControls.Label p_Label1;
UserCtrl1.ascx.cs
public System.Web.UI.WebControls.Label Label1 {
    get { return p_Label1; }
    set { p_Label1 = value; }
}
Page1.ascx.cs
UserCtrl1 uc1 = (UserCtrl1)LoadControl("~/UserCtrl1.ascx");
uc1.Label1.Text = "Foo";

Issue 9: Unable to switch to design view

The new Visual Web Designer built into Visual Studio 2005 is more strict about proper HTML than is Visual Studio .NET 2003. If your aspx page contains mismatched tags or poorly formed HTML, then the designer will not let you switch to design view inside Visual Studio 2005. Instead, you will be restricted to code view until you fix the problems. This issue occurs because of the new source code preservation and validation functions built into Visual Studio 2005.

How to fix

All you can do to avoid this issue is make sure that the tags in your aspx pages are well formed. If you encounter a problem switching from code view to design view post-conversion, then the problem is almost certainly a bad tag.

Issue 10: Unable to parse filename

You may see a slightly ambiguous error message informing you that a file could not be parsed. This means either the 'Codebehind' or 'Src' attribute could not be found above the HTML tag.

If your Web form or user control does not contain either of these attributes, then the wizard cannot find the matching code-behind file and cannot convert the page.

How to fix

If this happens to a pure HTML page then this error can be ignored—you will often encounter this error if your application has pure HTML pages that use the aspx extension.

To avoid this issue, make sure you name your html files appropriately and use the 'Codebehind' and 'Src' attribute in your Web forms and user controls above the HTML tag.

Note   in the next release of the Web project migration wizard, this error will be made more descriptive by using the following messages.

  • "Warning: Unable to parse file %1, since no code-behind attribute or page/control directive found."
  • "Warning: The code file %1 is not a valid code file."

Part 3: Other Conversion Issues

Here are other, less common conversion issues you may run across.

Issue 11: Backup folder in the Web project folder

As mentioned before, Visual Studio 2005 normally considers all files in a folder or sub-folder to be part of the Web project. By default, the conversion wizard will create a backup of your Web project in a safe location, but it is possible for the user to overwrite the default. If you put the backup folder in the Web application's folder tree, you will get this somewhat cryptic build error:

Error 1 - It is an error to use a section registered as 
allowDefinition='MachineToApplication' beyond application level

How to fix

Make sure your backup location is not in the Web application's root folder or sub-folder!

Issue 12: Multiple projects in the same location

If you have a Web project sharing a folder location with another project in the same solution, Visual Studio 2005 will consider all files found in that folder part of a single Web application.

If they are all Web projects and they are truly separate, i.e. self-contained, then converting those into a single Web application may not cause a problem. However, you may want to keep these projects separate if:

  • It is a mix of Web and client projects
  • Different code languages are used
  • Aesthetic reasons

How to fix

If they are a mix of Web and client projects, then simply move the client project files into their own folder.

If different code languages are used, it is recommended you move the Web projects into separate folders for conversion. Later, if you want to merge these Web projects into a single, multi-language Web application, review the Visual Studio 2005 documentation on structuring the App_Code folder and Web.config for multiple languages and merge your Web projects manually into a single Web application.

Issue 13: Multiple projects referring to the same files

If more than one project refers to the same set of files, then it is possible for those common files to be migrated twice.

How to fix

Make sure that a given file is only referenced by one project file.

Usually, multiple projects referencing the same set of files means there is a duplicate or old version of the project file in the folder. In this case you can remove or rename the extra project files to resolve the issue.

If there is a true need to have multiple Web projects refer to the same set of files, then it is best to move the common files into their own separate client project, and then have the multiple Web projects refer to that separate client project. Please refer to Step-By-Step Guide to Converting Web Projects to Visual Studio .NET 2005.

Issue 14: Invalid access modifier

After converting your Web project, you get an Invalid Access Modifier error.

Since Visual Studio 2005 now uses multiple assemblies, the access level to member variables and functions need to be modified if you want to access them from another assembly.

How to fix

Review your code and change the access level to allow access. Normally changing the modifier to public will solve the problem.

Note   You should always consider the security of the member variable or function before doing this, i.e. we do not recommend doing this blindly.

Issue 15: Converting excluded files

Excluded files will not be converted by the conversion wizard—so how can you get the conversion wizard to convert these files?

How to fix

Prior to conversion, temporarily include the file you wish to convert in your Web project and make sure its build action is not set to "none".

After the conversion, the file will be converted. You can then use Exclude from Project feature (found on the Solution Explorer menu) to exclude the file again.

Issue 16: Duplicate variable declarations

After conversion, you may find control objects declared via client scripts are also declared in the partial class. An example could look like the following:

File ASP.NET 1.x Code
Page1.aspx
function Form1_onfocus() {
   var myType = <asp:literal id="myTypeId" runat="server" />;
}
Page1.ascx.cs
protected Literal myTypeId;

How to fix

By design, the conversion wizard does not parse client script and will not catch this reference. To resolve, simply remove the declaration from the partial class and your code will compile.

File ASP.NET 2.0 Code
Page1.aspx
function Form1_onfocus() {
   var myType = <asp:literal id="myTypeId" runat="server" />;
}
Page1.ascx.cs
// protected Literal myTypeId;

Issue 17: Sub-Web applications

As mentioned before, Visual Studio 2005 normally considers all files in a folder or sub-folder to be part of the Web project. However, it is possible to designate a sub-folder as its own Web application by using the IIS manager (inetmgr) to set the sub-folder as an IIS virtual folder. When Visual Studio 2005 discovers this virtual folder, it will not consider it part of the Web application. This works if you open your Web project via HTTP.

The problem occurs if you open the Web project via File Location. In this case, Visual Studio 2005 will not know it is an IIS configured Web application and will not discover the IIS meta-information stating a sub-folder is a virtual folder. Visual Studio 2005 will now try to open and compile the Web application along with the sub-Web application.

The conversion wizard will give you the following warning if you convert a file-based Web project.

Warning: This Web project was converted as a file-based Web application. If your site contained any IIS meta-information, e.g. sub-folders marked as virtual directories, it is recommended that you close this Web site and re-open it using the Open Web Site command and selecting the Local IIS tab.

How to fix

Be sure to mark sub-Web applications as virtual directories using the IIS manager (inetmgr), and to open the Web project via HTTP rather than File Location so the IIS meta-information will be found.

Issue 18: OnInit() not removed

In Visual Studio .NET 2003, the designer added auto-generated member functions OnInit() and InitializeComponent() to the code-behind class file. These functions are not used by Visual Studio 2005 but will be called if they exist. The functions are not removed by the conversion wizard.

This behavior is by design since the wizard does not know if user code exists within these functions, so the code is left as-is in the code-behind file.

How to fix

After reviewing the functions to make sure there is no user code that should be saved, remove these functions from the code-behind file.

Aa479312.oninit(en-us,MSDN.10).gif

Issue 19: XHTML validation errors

After converting your Web project, or when opening a converted Web project, you see XHTML validation errors in your error window after building your Web project.

This is a feature of Visual Studio 2005, and is designed to help you write more XHTML compliant code. (Click the graphic below for a larger image.)

Click here for larger image

How to fix

To fix, you should change your code to match the level of XHTML standard you are targeting. For example, a strict level would be "XHTML 1.1".

If you want to turn off the showing of these errors, you can set the validation level to a less strict level. By default, when a Web project is converted, the validation level is set to "Internet Explorer 6.0" which is close to the validation level used by Visual Studio .Net 2003.

You can set the validation level by clicking Tools, then selecting Options, and then selecting the appropriate level on the Text Editor/HTML/Validation dialog.

Aa479312.xhtmlval(en-us,MSDN.10).gif

Issue 20: Multiple configurations

Visual Studio .Net 2003 allowed Web projects to have multiple configurations, e.g. Release and Debug, to configure your build and deployment environment.

Visual Studio 2005 only supports one configuration per Web project. During conversion, the Debug version is the default unless a custom configuration is found. In this case, a dialog will prompt you to choose the configuration to use in the converted Web project.

How to fix

As a workaround, use two or more Web configuration files corresponding to the configuration you want to support. Copy the version you want to use to Web.config during your operation.

For example, you could have a Web.config.release file for your release configuration and a Web.config.debug for your debug configuration. Copy the appropriate one to Web.config when debugging or deploying your Web project.

Note   Web Deployment Projects, a technology preview feature available as a VSIP add-in for Visual Studio 2005, will provide true configuration support for Web projects. See the "Visual Studio 2005 Web Deployment Projects" white paper on https://msdn.microsoft.com for more detail.

Issue 21: Auto-generated members hide inherited members

If you use base classes to define control variables (Label1, for example) or event handlers for use in derived classes, then you might find that these members are hidden by auto-generated members for the page's partial class in Visual Studio 2005.

Visual Studio 2005 generates the page class and does not normally see the inherited members. So it would generate control variables or event handlers that would hide the inherited members.

How to fix

ASP.NET 2.0 provides a new attribute called CodeFileBaseClass to handle this situation. The @Page and @Control directives now support this new attribute, which specifies the grandparent class for a page. The compiler uses this attribute during class generation to get a reference to the page's base type and generate code that does not hide inherited members in the base type

File ASP.NET 2.0 Code
Base.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Base.aspx.cs" Inherits="myBase" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
</head>
<body>
    <form id="form1" runat="server">
    <div>
        Base<br />
        <asp:Button ID="Button1" runat="server" 
         Text="Button" OnClick="Button1_Click" />
        <asp:Label ID="Label1" runat="server" 
         Text="Label"></asp:Label></div>
    </form>
</body>
</html>
Base.aspx.cs
public partial class myBase : System.Web.UI.Page {
  protected void Button1_Click(object sender, EventArgs e) {   
        Label1.Text = "Base";
}}
Derived.aspx
<%@ Reference Page="~/Base.aspx" %>
<%@ Page Language="C#" AutoEventWireup="true" 
CodeFileBaseClass="myBase" 
CodeFile="~/Derived.aspx.cs" 
Inherits="myDerived" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        Derived<br />
        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label></div>
    </form>
</body>
</html>
Derived.aspx.cs
public partial class myDerived : myBase
{
 // This is commented out since we will use 
 // the inherited functions and variables
 // protected void Button1_Click(object sender, EventArgs e)
 // {
 //    Label1.Text = "Derived";
 // }
}

Issue 22: Ambiguous references and naming conflicts

The .NET Framework 2.0 adds a host of new namespaces and classes. Several of these are likely to cause clashes with ASP.NET 1.x applications. For example, the new personalization features introduce classes with the names of Profile, Membership, and MembershipUser. The Profile name, in particular, is fairly commonly used by developers who want to keep track of user information. Therefore if you have a Profile class in your application, and you try to use any of the new personalization features, you may encounter compiler warnings about ambiguous class references.

How to fix

Planning ahead for naming conflicts can be rather difficult. You will want to take a quick look through the new ASP.NET classes. If you see any names that might conflict with what you have in your application, you might consider using explicit naming. For example, use System.Web.Security.Membership instead of importing/using System.Web.Security and then using the Membership class.

Issue 23: Event handlers called multiple times

Because of the way that the conversion wizard merges code-behind files and aspx pages, you may encounter scenarios where an event gets called twice (page load, for example). This scenario occurs if you had event wireup code in your code-behind file that wasn't in the InitializeComponent method. The conversion wizard is only smart enough to remove duplicate wireups if they are in the InitalizeComponent method.

You may have a difficult time noticing this error because in most cases a second event firing will be harmless. However, if you do discover that an automatically called event is occurring multiple times, you should examine your converted code-behind file to see if the handler has been wired to the event twice. If so, you will have to manually remove the second wireup.

How to fix

You can avoid this issue entirely by scanning your existing code and making sure that all event wireups are contained in the InitialzeComponent function for the code-behind file or by setting AutoEventWireUp=False in your page.

Issue 24: Code-behind files moved to the App_Code folder

After the conversion wizard runs, you might find some of your code-behind files (*.aspx.cs or *.ascx.vb, for example) moved to the App_Code folder.

This usually indicates your content page has a malformed Codebehind directive and is not set correctly to the code-behind file. In other words, the conversion wizard wasn't able to determine that the code-behind file was actually tied to a specific aspx page.

The conversion wizard will automatically move all standalone class files (for example *.cs or *.vb) to the App_Code folder. If you have a malformed Codebehind directive, then the code-behind file will be considered a standalone class file and moved to the App_Code folder.

Note   Web service files (e.g. *.asmx and *.asmx.cs) are different from normal content pages and their code-behind page. The code-behind for a Web service file is meant to go in the App_Code folder, so if you find one there it is not an error.

It is also possible that a Web form or user control was migrated twice—see the Multiple Web Projects Referencing the Same Files issue for ways to correct this issue.

How to fix

Prior to conversion, you can avoid this issue by making sure your Codebehind directive is correctly set in all your content pages.

After conversion, move the code-behind file to the same folder as the associated content page and correct the content page's Codefile (renamed in ASP.NET 2.0) directive to point to that code-behind file.

Issue 25: Projects referencing a Web project

In Visual Studio .Net 2003, it was valid to have a project reference a Web project's assembly. This will not work in Visual Studio 2005 since Web projects create multiple assemblies and the file name of the assembly can change from build to build.

How to fix

Prior to conversion, you will need to move common, shared code to a separate class library, and reference that library instead.

If you are using shared user controls, then you will have to create base classes that exist in the class library to be referenced by the other projects, and have the Web project's user controls derive from them.

For more information on this design pattern, refer to Step-By-Step Guide to Converting Web Projects to Visual Studio .NET 2005.

Issue 26: Sharing the same code-behind file

It is possible to have several pages share the same code-behind class file. This may be by user design or a result of copying a Web form or user control and not updating the @Page directive properly.

This can confuse the ASP.NET 2.0 compiler, which expects each Web form or user control to contain a unique code-behind file. You may get build errors or invalid run-time behavior when running the converted code.

How to fix

Prior to conversion, change your code to use a unique code-behind file for each Web form and user control.

If you wish to share common elements between several Web forms or user controls, then move those common elements to a base class, and have the Web forms or user controls derive from that base class.

Issue 27: Partially converted solutions

In both Visual Studio .NET 2003 and Visual Studio 2005, it is possible to have a solution that contains both Web projects and client projects, for example a C# or Visual Basic class library or Windows application

If you are using an express product, such as Visual Web Developer or Visual Basic Express Edition, you will be able only to convert projects in the solution that relate to the express product. For example, if you are using Visual Web Developer and open a solution with a Web project and a Visual Basic class library project, only the Web project will be converted, leaving you with a partially converted solution.

How to fix

You should use either the Standard, Professional, or Team System editions of Visual Studio 2005 to convert solutions containing multiple, mixed project types.

If that is not possible (you have only an Express edition), then you should create a new solution containing only the supported project type.

Issue 28: No command-line migration for C#

Command-line migration for Visual Basic Web projects is possible by using the command "devenv.exe <PorSfile> /upgrade", where <PorSfile> is a Visual Basic Web project file or a solution containing such a file.

Unfortunately, a C# bug was found late in the product cycle where an invalid C# code model is given to the Web project conversion wizard. As a result, errors are introduced to the Web application during a command line C# Web project conversion.

Since command-line conversion is considered a secondary feature as compared to converting via the user interface, and a C# fix for this bug threatened the release date for Visual Studio 2005, the bug was not fixed in the final release.

How to fix

There is no fix but the workaround is to use the user interface to open and convert the Web project or the solution containing the Web project.

Issue 29: Batch = True or False

As mentioned in Web Project Changes, the ASP.NET compiler's default behavior is to compile all Web forms and user controls in a folder into its own assembly. The Batch attribute can be set in Web.config to change the compiler's behavior.

For example, the following code segment will direct the compiler to compile a given Web form or user control into its own assembly (creating more assemblies than normal).

File ASP.NET 2.0 Code
Web.config
<configuration>
    <system.Web>
        <compilation batch="false">
        </compilation>
    </system.Web>
</configuration>

There are several issues you should be aware of when using this attribute.

  • Performance—when Batch=false, the ASP.NET compiler will create an assembly for every Web form and user control in your Web application. It also causes the compiler to do a full compile, not an incremental compile, in Visual Studio 2005 when you build using F5. The net result is your Web application may run slower when deployed, and your build times will increase significantly in Visual Studio 2005.
  • Assembly References—the Batch attribute may hide potential broken assembly references (when Batch=True), or even introduce a Circular Reference (when Batch=False).

How to fix

After you run the conversion wizard on a Web project, you should temporarily set Batch=False while you finish the manual steps to convert your Web project. This will make sure you catch any assembly reference issues.

After your Web project is fully converted, you should set Batch=True for normal development and deployment.

Note   When you deploy your Web application, you should do one final check with Batch=False to make sure no assembly reference issues were introduced during development of your Web application. After you have done this check, be sure to turn Batch=True again.

Summary

Converting an application from Visual Studio .NET 2003 to Visual Studio 2005 is generally a smooth process. However, you have to make sure that your development and deployment environments are properly configured. You also have to evaluate your conversion report to resolve any potential issues not handled by the conversion wizard. You may also wish to review your application ahead of time and plan ahead to avoid known issues with the conversion.

Future Releases

Given the importance of Web project migration, we are always looking for feedback to improve this experience. We plan to update the migration wizard as needed even after the official release of Visual Studio 2005 in November 2005. If you have questions or feedback, then please post them to the "Visual Studio .NET 2003 to Visual Studio 2005 Migration" forum located at http://forums.asp.net.

Appendix A: Actual Error Messages

Actual Error Message Origin Possible Issue(s)
Error 1 – The name 'Page1' does not exist in the current context Build Error Code-behind class file (CB-CB) references

Stand-alone class file (SA-CB) references

Error 1 – File 'Page1.aspx.cs' was not found Build Error Multiple projects referring to the same files
Warning: Code-behind file 'Page1.aspx.cs' is marked as code-behind for 'Page2.aspx' too. This may cause build errors Conversion Wizard Sharing the same code-behind file
Warning: This Web project was converted as a file-based Web application. If your site contained any IIS meta-information, e.g. sub-folders marked as virtual directories, it is recommended that you close this Web site and re-open it using the Open Web Site command and selecting the Local IIS tab Conversion Wizard Sub-web applications
ERROR: The member declaration for 'Label1' was removed and its accessibility has been changed from 'public' to 'protected'. To access this member from another page you should create a public accessor property for it Conversion Wizard Accessing an auto-generated control variable
ERROR: The following files were not migrated because they were not found in the project file or the associated 'BuildAction' is set to 'None'. You may need to exclude these files from the project after the conversion process in order to compile your Web site: File List == Page1.aspx,
Page1.aspx.cs
Conversion Wizard Excluded files are no longer excluded
Warning: Resource files were moved to 'App_GlobalResources' folder. Code using resources may have to be fixed manually Conversion Wizard Resource Manager
Error 1: Could not load type 'myApp.Page1' Build Error The Codebehind directive is pointing to an unconverted file. See Excluded files are no longer excluded.
Error 1: 'myApp.Control1.Label1' is inaccessible due to its protection level Build Error Invalid access modifier
Server Error in '/myApp' Application. Could not load file or assembly 'myApp' or one of its dependencies. The system cannot find the file specified Server Error Resource Manager
Error 1: Validation (XHTML 1.1): This name contains uppercase characters, which is not allowed Build Error XHTML validation errors
Error 1: It is an error to use a section registered as allowDefinition = 'MachineToApplication' beyond application level Build Error Backup folder in the Web project folder

Sub-Web applications

Cannot switch to Design view because of errors in the page. Please corrrect all errors labeled 'Cannot switch:' in the Error List and try again Error Dialog Unable to switch to design view
Error 1: File 'Page1.aspx.cs' was not found Build Error Multiple projects referring to the same files
Error 1: Circular file references are not allowed Build Error Circular references

© Microsoft Corporation. All rights reserved.