Thursday, July 16, 2009

Migrating from .net Framework 1.1 to .net Framework 3.5

We are looking at the painful task of migrating from .net Framework 1.1 (scary I know) to .net Framework 3.5. I couldn't get any thorough material on the topic, so I decided to post my finding to help anyone else who has the painful task of migrating.

Firstly ask yourself the question, "Do I really have to migrate?". If this is the case, I can tell you that migrating web application is more of a pain then win application, due to all of the core changes on in 2.0. My research is mostly based on migrating win apps, but is also applicable to web apps.

Visual Studio 2008 is a superset of Visual Studio 2005 and given framework multi-targeting and the layered approach of Framework 3.0 and 3.5, it makes perfect sense to move your development environment over.

When migrating from Visual Studio 2003 the issue is that: you are on a different CLR version (1.1) which has some breaking changes compared to the CLR 2.0 (which is used by Fx 2.0/3.0/3.5). You are also on a different framework version (1.1) which has some breaking changes compared to Framework v2.0 (which is also an essential part of Fx 3.0/3.5). There is no reason for you to go to VS2005 as an intermediate step, so by all means go from the IDE of 2003 to 2008, but be prepared to face all the issues people faced when they moved from Fx 1.x to Fx 2.0.

Breaking changes are categorized in design-time changes (Visual Studio changes: design, compile, project upgrade) and runtime changes (.NET Framework). Runtime changes impact application compiled with 1.0 or 1.1 running on 2.0, but can also impact application originally written in 1.0 or 1.1 and then recompiled for 2.0. Instead, design-time changes do not impact application compiled for 1.0 or 1.1 and just running on 2.0. You just get design time changes if you recompile your application to 2.0. So, my advice is of course to have a look to this list and if your application implements one of the presented issues, then implement the described workaround.

Migration Steps

  1. Make Backup
  2. Open the application in VS2008 and run it through the conversion wizard.
  3. Check out the list of breaking changes.(below)
  4. At this point, the most common error will be conflicts with names that have been introduced. For example, the new personalization feature introduces classes with the names like Profile, Membership and Operator. To fix this kind of error, you can either fully qualify existing names with a namespace or rename the members so they do not conflict. Often, name-related problems can be solved by enclosing the offending term in brackets (e.g., "[_Operator]").
  5. You will maybe get warning about using obsolete members. When you get a warning of this type you always get an alternative method to call (the compiler suggests you to use another method).
  6. Finally start the application and validate all the functionality.

Migrating from 2.0 to 3.5 requires some changes because there is a new assembly that has been added alongwith System.Data. The new assembly is System.Data.DataSetExtensions which has some DataSet properties transferred from System.Data.

If you plan to convert from 2.0 to 3.5 and if you are using System.Data with dataset in existing project, the dataset extension properties will not comppile.

The solution will be simple when converting .prj file to use framework 3.5 you have to add new assembly reference to it.

Check these very interesting posts on migrating. It will help us a lot

Microsoft .NET Framework 1.1 and 2.0 Compatibility

Compatibility Testing Scenarios



Below is a list of all of the breaking changes made in the newer versions. The links next to the issues contain the work around solutions.

.net 2.0

Design Time Breaking Changes


      • Delegate Co and Contra variance effect binding
      • Protected constructors can no longer be called
      • Conditional Grammer ambiguity
      • Ambiguity between comparison and generic definition
      • Redefinition of Dispose() no longer allowed
      • Cscompmgd.dll is now obsolete
      • /incremental flag generates warning
      • Referencing two types with the same name from different dlls generates error
      • Compat: Migrating an RTM project containing an “invoke” doesn’t compile in v2.0
      • Params on an explivit impl shouldn’t be allowed unless it’s also on the interface method
      • Changes to the way we convert to/from Booleans in Jscript result in more ambiguities in resolving multi-argument methods
      • Referencing multiple assemblies with the same type gives compiler error
      • Having a filed with the same name as an internal class doesn’t compile
      • Sealing a property with just the getter (or setter) seals both of then in v2.0
      • In v1.1 the compiler would allow an explicit implementer to add the params modifier. In v2.0 we report and error


· Design time connection string will not get upgraded automatically from native ODBC to managed client when upgrading a VS6 database project. Data designers in v2.0 do not work with ODBC connections.

Visual Studio

· Solution configuration changes after migration so that a peoject will be marked “Do not build” even though it was marked to be built, for solution with the same GUID

· Extensibility no longer uses Microsoft.Office.dll

· Build Error after migrating an application that compiles in VS2003: Invalid characters in resx files

Windows Forms Design

· V1.1 Controls with an AutoSize property that is not a Boolean will throw an exception when used in the v2.0 designer

CLR Design

· Aligning TlbeExp behavior with run-time behaviour

· New String.Split overloads make certain existing calls ambiguous

· System.DirectoryServices.SearchWaitHandler class is removed

XML and Serialization

      • Generating poperties not fields will break existing code using regenerated proxy for some languages
      • Generated Proxy contains XmlNode[] instead of Object[]
      • Regression in code generation for from xsd schema while using choice
      • XslTransform throws IncalidOperationException in v.2.0, XsltException in v1.1
      • After updating a web reference the user may see an error ( CS0029)
      • After updating a web reference the user may see the following run-time exception: Value of ItemsElementName mismatches the type of custClass; you need to set it to ItemsChoiceType.@custData1

Run Time Breaking Changes


      • Three overloads of Marshal.WriteInt16 that accept char as one of parameters write only one single byte
      • TlbExp naming generation change
      • Trailing slash behavior changes for DirectoryInfo.Parent, and Name
      • NativeOverlapped constructor changed from taking an int to IntPrt
      • Greater precision introduced in Floating Point calculations
      • Some DateTime Parsing which was acceptable but interpreted badly, is now no longer accepted
      • ToString behavior on RegistryKey has been modified
      • Check the type of type(class vs. struct) specified in a TypeRef in metadata to ensure that is correct. A TypeInitializationException will be thrown if the TypeRef is incorrect.
      • WaitHandle.Wait* will throw when the wait completes due to an abandoned mutex will continue to be held
      • The 2.0 runtime looks for and consumes the /cor command line switch on all applications
      • Throw AccessViolationException when an AV reaches managed code
      • Unhandled exceptions will always be fatal to a process
      • Adding unmanaged code permission link demand on some of the functions in the tracing classes
      • Disable inheriting from COM invisible classes and making derived classes COM visible
      • GetTypeFromCLSID returns the same type always, regardless of environment
      • This breading changes rewuest has two parts: 1) Always initialize main method as MTA usless user specified [STAThreadAttribute] on the main method. 2) Always initialize new threads as MTA unless user initialized it STA before thread started
      • UTF7Encoding need to override the Equality
      • Change the Equality operation in SortKey class
      • StringInfo need to implement the Equality and GetHashCode
      • UTF8Encoding needs to change Equals() implementation to consider throwOnInvalidBytes
      • Encoding.GetBytes() may not emit unpaired high or low surrogate characters for certain encodings (e.g. UTF-8 encoding and UnicodeEncoding)
      • Breaking Change: DisplayName of version 2.0 assemblies to contain processor architecture
      • CompareInfo.GetSortKey should throw an exception when CompareOptions is out of range
      • Change SortKey.GetHashCode() to match SortKey.Equals() behavior
      • RSACryptoServiceProvider and DSACryptoServiceProvider delay creation of a random key, causing exceptions to be thrown later than they were before
      • Kyrgyzstan tag is now KG, matching official ISO tag
      • Globalization: DateTimeFormatInfo; ‘U’ format string for Datetime are missing
      • DATA: Breaking Change – 4 cultures (ar-MA, nn-NO, kn-IN & div-MV) have misspelled day or month names
      • DATA: Breaking (rarely) month/day name changes
      • Breaking Change: _Module in System::Runtime::InteropServices conflicts with global CComModule(ATL) object _Module
      • DCR to make Boxed Value Types read-only
      • String comparison and sorting for sr-SP-Latin(Serbian) culture is incorrect
      • Type.GetType(String typeName) throws if the type name contains the ‘&;’ character
      • Canonicalization issue affecting Demand semantics in FileIOPermission
      • BCL: StringBuilder constructor doesn’t work as expected if capacity=0 and Maxcapacity 16/td>
      • Behavior change: % format produces different results under version 2.0 and EVE
      • StreamReader used to ignore invalid UTF-* characters. Now it replaces them with “?”
      • Order of invocation of cctors has changed from v1.1 to v2.0 for beforefieldinit types in NGENed code
      • Environment.UserDomainName now returns the correct value for name conflict scenarios
      • Cache load failures in order to ensure that different app domains do not have different dependency loading success/failure characteristics in domain neutral sharing scenarios
      • Change Activator.CreateInstance and Type.InvokeMember to determininstically choose binding preferences, rather than depending on declaration order
      • Enterprise Library June release configuration tool fails when run against v2.0
      • NullReferenceException when calling GetEnumerator on a SynchronizedHashtable cast to ICollection
      • Releasing an unowned monitor throws an exception
      • WaitHandle.WaitAll throws an exception that seemingly cannot be caught if ther’s a null element in the array of wait handles; this is different from v1.1 behavior
      • Applications dependent on the implementation of private fields could be broken if the type of the filed changes for example from an IntPtr to a SafeHandle
      • String.GetHashCode and Object.GetHashCode algorithms have changed
      • Stack Trace was misreporting nested classes in v1.1, this has been fixed in v2.0
      • Private typedefs may not have the same name in assemblies built for v2.0 as they did in v1.1
      • Loadform after Load bypasses Load context cache, and now loads for Cache
      • Unhandled exceptions will always be fatal to a process
      • Order of invocation of class .ctors is changed from v1.1 to v2.0 for beforefieldinit types in NGEN
      • A LockCookie for one ReadWriterLock can be used to restore a different ReadWriterLock
      • The values inside 2 enums (PerformanceCouterPermissionAccess and AttributeTargets) have changed
      • V1.1 stores raw handles in the WaitHandle.Handle property, while v2.0 wraps all raw handles in a SafeWaitHandle
      • Code that calls virtual functions non-virtually in partial trust fails with a System.Security.VerificationsException when run against .NET Framework 2.0


      • Assembly.Load* will prefer the serviced version of the assembly in the GAC to enable the central servicing scenario
      • Remove native image support in the assembly cache viewer. Current support causes confusion and leads to inconsistent state
      • Changed assembly textual identity (display name parsing/generation rules)
      • Binding succeeds with http config as appbase where in v1.1 it thres an exception


      • SortKey.GetHashCode() was incorrect in v1.1 and has been fixed in v2.0
      • 7 bit encoding behavior changed to remove insecure mapping when 8th bit is set
      • String comparison (and sorting) for sr-SP-Latn (Serbian) culture is incorrect
      • Misspelled culture day & month names were corrected. Culture data is unstable and should not be relied upon
      • Update Turkish currency to New Turkish Lira (YTL)
      • Encoding.Unicode.GetMaxCharCount returns different sizes than previous versions
      • ‘U’ format in DateTime.ToString() has different behavior for Japanese Calendar between
      • The culture identifier ky-KZ was changed to ky-KG to match international conventions
      • UnicodeDecoder throws when handling surrogate characters


· RejectChanges() to have cascade semantics like AcceptChanges, it is to be independent of the current DataRow state

· V2.0 has a new set of Performance Counters that are specific to each provider; all counters in the .NET CLR Data category have been obsoleted

· In 1.0 and 1.1 if a user does not specify a value or set the Size to zero on the Parameter object the Size was reported as Zero for OleDB, Odbc, OracleClient. Internally these 3 providers, we inferred the size and when we bound the parameter to the underlying stream to send to the server, we inferred the size and reported that to the server. SqlClient inferred from the value if a value exists and reported this inferred size.

· In v1.1 DataTable.rows.Remove(row) does not actually remove rows that are in ‘deleted’ state. Removing is conditional, based on the state of the row being removed

· Introducing type checking for UDTs/Object, may break applications relying on *no* type checking

· The new XML inference engine assigns different Column ordinals in some specific cases

· Deprecated unused property DataTable.DisplayExpression in v2.0

· DataRow is cleared when the value of one column (cell) is changed

· XSD: a Fixed value compares to be the same as in the schema, even though it has multiple Cyrillic-E ( 0x0400) characters

· XmlDataDocument uses internal APIs to create partially initialized DataRows. A DataSet containing such rows if merged into an empty DataSet may result in a constraint violation exception in version 2.0. In v1.x, no exceptioni was being thrown

· Introducing type checking for UDT DataColumns may break applications relying on *no* type checking

· The behavior of LinePosition in XmlTextReader.ReadChars method differs between v1.1 and v2.0

· Casting the return value from SqlHelper.ExecuteXmlReader to an XmlTextReader, worked reliably in v1.0 and v1.1. In v2.0 this may throw a cast exception, indicating the underlying type was an xmlTextReaderImpl.

· In v2.0, DataView[DataRowView.Index]== DataRowView while this was not guaranteed to v1.x

· In v1.x DataSet.Merge(DataRow[] rows) used to use DataTable.TableName to lookup tables in DataSet whereas c 2.0 uses the combination of DataTable.Namespace and DataTable.Name to lookup tables. This results in a change of semantics for v2.0 Merge.

Enterprise Services

· AuthenticationTypes.Secure will be used as the default authentication type for DirectoryEntry

Windows Forms

· Addition of missing values to the KnownColors enum in order to support new System Colors

· TabControl Enter and Leave events are raised for Tabs being clicked in addition to when focus leaves a TabPage

· Mouse Enter and Leave events are now raised for scrollbars and ScrollableControl

· Calling TreeNode.Bounds.Location in the Form’s Load event returns 0,0

· The first RadioButton in a group doesn’t become checked when the first RadioButton in the group gets focus

· No KeyPress event for (Char) 127 + different handling comparing th v.1.x

· ComboBox.PreferredHeight does not return the correct value as expected

· BindingContextChanged event fires less number of times when LB is added/removed to a form

· January PAG blocks are broken on v.2.0

· Layout events occr more frequently and earlier in v2.0 than in v1.1

· The Cursor property is now respected for the ComboBox Text area

· Windows Forms will now throw an IllegalCrossThreadException when a debugger is attached and a property of a control is accessed from a thread it wasn’t created on.

· Backgrounds that were transparent in v1.1 are showing up as grey in v2.0

· Setting the ImageList.Stream property to null now clears the images in the list

· Controls with a FlatStyle property now render using VisualStyles with FlatStyle.Standard set

· Accessibility changes completed in v2.0 may affect users using an accessibility reader

· Windows Forms parameters have had some name changes

XML and Serialization

· MarshalByRef should be removed from System.Uri signature

· Bug fix for invalid URI construction logic when working with a URI scheme unknown to System.Uri

· If a callback function of an asyn delegate throws an exception, the callback will be invoked twice

· If a MBR object (whick already has an identity) is cloned, the identity is cloned as well, whick means any future remote calls to the cloned object get dispatched to the original object

· Invalid nntp and news URI’s should not be considered valid by System.Uri

· When creating a WebPermission with Regex people usually go with a simple regex like this: new Regex(“*”) When user wants to Deny on above created permission, there are many ways to by-pass that user requirement by using a URI string with userinfo and/or explicit port, so the regex won’t match. To improve WebPremission story with Deny we want to canonicalize the user URI string by roundtriping it through System.Uri class and also we want to strip userinfo part before calling Regex.Match(). As the result some WebPermission form like using the following Regex will stop working new Regex(“http:/*”). This is because we strip default port as part of URI string canonicalization so Regex parser will not find it anymore hence won’t match

· Supporting Nullable by default can break existing code when proxy is re-generated

· Uri.LocalPath returns excaped string for HTTP in version 1.1 but unescapes the string in version 2.0

· HTTP: now throws a parsing exception

· MarshalByRef removed from System.Uri signature

· We throw when generating WSDL if the service has duplicate [WebServiceBinding(Name=…)]

· Breaking Change – [WSS – PD7 – P2] System.Net.WebClient.UploadValues() method adds to the end of its output in ciolation of the application/x-www.form-urlencoded content type encoding scheme

· ASP.NET Web Service requests always send the AcceptEncoding: gzip HTTP header on v2.0

· Whenever an HttpWebResponse gets a 404. 500, or other error from the server, we automatically read a portion of the response content into memory and attach it to a WebException.

· GlobalProxySelection.Select behaves differently from v1.1 when an empty tag is present in machine.config

· The proxy by pass list now has escaped(regex) significant characters

· NetworkStream now honours the FileAccess parameter.

· The wrong version of assembly may be loaded when deserializing in Simple mode

· XML Serialization generates AssemblyResolveEvents in v2.0 but not in v1.1

· The default for serializing DateTime is RoundTrip which is breaking

VS tools and Office

· VSTO orkloadr requires .net 1.1 to load policy

.net 3.0

The .NET Framework version 3.0 was issued solely to include the following technologies in the .NET Framework and in the Windows Software Development Kit (SDK):

Windows Communication Foundation

Windows Presentation Foundation

Windows Workflow Foundation

Windows CardSpace

There were no feature changes to the core .NET Framework for this version.

.net 3.5

.net 3.5 SP1

Breaking Changes SP1

Common Language Runtime

Performance Improvements – NO MODIFICATIONS REQUIRED



Queries over non-generic collections now use standard C# cast semantics MODIFICATION



Integrated Windows authentication MODIFICATION


ASP.NET request validations MODIFICATION


Session states MODIFICATION



Server and client number formatting consistencies – NO MODIFICATIONS REQUIRED


Windows Presentation Foundation (WPF)

BitmapEffect classes are obsolete MODIFICATION

Assembly name change– NO MODIFICATIONS

Hyperlink behavior– NO MODIFICATIONS

Internet Explorer in Protected Mode on Windows Vista – NO MODIFICATIONS REQUIRED

CanConvertToString methods on ValueSerializer classes – NO MODIFICATIONS REQUIRED

Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF)


Security improvements for authentication MODIFICATION

Partial trust support for event logging – NO MODIFICATIONS REQUIRED

RemoteEndpointMessageProperty availability – NO MODIFICATIONS REQUIRED

Running multiple .net Frameworks on the same server

Migrating To Visual Studio 2008 & .Net Framework 3.5

1 comment:

  1. A gripping read. I recommend this to all and sundry.