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:
- Before Conversion – reviewing and possibly altering your Web project architecture before running the conversion wizard.
- Conversion – running the Visual Studio 2005 conversion wizard to convert your Web project.
- 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.
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!
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.
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.
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.
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.:
It can also happen between assemblies, where one assembly references another
assembly, which in turn references the original assembly, e.g.:
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.
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.
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.
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.)
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.
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
|
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 |