Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Migration Issues for .NET Framework 4 Applications: Beta 2 to RTM

Migration Issues for .NET Framework 4 Applications: Beta 2 to RTM

This topic describes migration issues between the .NET Framework version 4 Beta 2 and version 4 RTM, including fixes, changes for standards compliance and security, and changes based on customer feedback. Most of these changes do not require any programming modifications in your applications. For those that may involve modifications, see the "Recommended changes" column of the table.

For migration issues for .NET Framework version 3.5 SP1 applications, see .NET Framework 4 Migration Issues in the .NET Framework documentation. For information about new features, see What’s New in the .NET Framework Version 4.

This topic describes changes in the following areas:

  • Core
  • Networking and Remoting
  • Office
  • Workflow

Core

Feature

Differences from .NET Framework Beta 2

Recommended changes

Assembly and Module classes

An inheritance demand for full trust was added to the System.Reflection.Assembly and System.Reflection.Module classes for RTM.

Partially-trusted types that were derived from Assembly and Module in Beta 2 now must be fully trusted.

Performance counters

In the .NET Framework 4 Beta 2, the common language runtime (CLR) looked up a counter name by using localized data regardless of whether the localized category name was the same as the English category name.

In the RTM release, if the English category name is the same as the localized category name, the CLR uses English data to look up the counter name. The RTM behavior is the same as the behavior in the .NET Framework 3.5 and earlier.

To avoid conflicts, do not use a localized category name that is the same as the English category name.

ResourceManager

The .NET Framework 4 RTM no longer uses the operating system-preferred fallback cultures for a System.Resources.ResourceManager object. Instead, the CLR searches only the parent chain of the requested culture, and ignores any fallback settings in the operating system. If those cultures are not found, the default resources are used as a last resort before throwing an exception. For more information about this logic, see Packaging and Deploying Resources in the .NET Framework 4 documentation.

None. Even if you annotated your neutral resources with the NeutralResourcesLanguageAttribute attribute to work around this new behavior, the attribute should remain on your assembly, because it provides useful information to the ResourceManager.

Type.IsValueType property

The System.Type.IsValueType property value for a generic type parameter that has a value type constraint has changed as follows:

·         true in the versions before .NET Framework 4 Beta 2.

·         false in the .NET Framework 4 Beta 2.

·         true in the .NET Framework 4 RTM.

The behavior is the same whether the type parameter belongs to a generic type or to a generic method.

The following example demonstrates how to get this value for type parameter T of the generic type Nullable<T>:

using System;

class Program

{

    static void Main(string[] args)

    {

        Type t = typeof(Nullable<>);

        var o = t.GetGenericArguments();

        if (o[0].IsValueType)

            // true in .NET Framework 4 RTM and

            // versions before Beta 2.

            Console.WriteLine("Must be a value type.");

    }

}

None, unless you used workarounds to correct the conflict that has now been resolved.

Networking and Remoting

Feature

Differences from .NET Framework Beta 2

Recommended changes

IPC channel

In the .NET Framework 4 Beta 2, if a user who has administrative credentials creates a named pipe in the IPC channel, the security ID (SID) for that user is added to the discretionary access control list (DACL). However, this enables the user to access the named pipe even if that user loses administrative credentials.

In the .NET Framework 4 RTM, the new System.Runtime.Remoting.Channels.Ipc.IpcChannel constructor enables you to change the security descriptor in the named pipe so that the previous values of the security descriptor can be restored. This constructor helps improve security by using a parameter that takes a custom security descriptor, which overrides the default settings.

None. If you have been specifying your own security descriptor, you can now use the new IPCChannel constructor.

Office

Feature

Differences from .NET Framework Beta 2

Recommended changes

Office projects

If you used Visual Studio 2010 Beta 2 to create a Microsoft Office project that targeted the .NET Framework 4 (see Office Development in Visual Studio), the project will not compile in Visual Studio 2010 RTM.

To compile the project in Visual Studio 2010 RTM, you must regenerate the code-behind files. There are two ways to do this.

Option 1:

1.    Verify that the project is not open in Visual Studio 2010.

2.    Delete all the files that have the .Designer.cs or .Designer.vb extension from the project. For example, for a Visual C# add-in project, delete ThisAddIn.Designer.cs file.

3.    Open the project in Visual Studio 2010. Visual Studio automatically regenerates the deleted files with code that compiles.

Option 2:

4.    Open the project in Visual Studio 2010.

5.    Change the target .NET Framework of the project to the .NET Framework 3.5.

6.    Change the target .NET Framework back to the .NET Framework 4 or to the .NET Framework 4 Client Profile. After you retarget the project, Visual Studio automatically regenerates the deleted files with code that compiles.

Important: This solution applies only to Office projects, and not to Windows Forms or other projects that create designer files.

Workflow

Feature

Differences from .NET Framework Beta 2

Recommended changes

FlowChart designer

The FlowSwitch item in the Activities toolbox now creates a generic System.Activities.Statements.FlowSwitch<T> class instead of a non-generic FlowSwitch class. This is because the non-generic class was limited to switching only on strings, whereas the generic class enables you to switch on any type of T.

Flowcharts that use a FlowSwitch and were authored by using the Windows Workflow Foundation (WF) designer in the .NET Framework 4 Beta 2 will not load in the new WF designer.

Edit the Flowchart XAML to add x:TypeArguments="x:String" to the FlowSwitch node:

<FlowSwitch x:TypeArguments="x:String" Default="{x:Reference __ReferenceID2}" x:Name="__ReferenceID3" Expression="[variable1]">

  <x:Reference>__ReferenceID0<x:Key>Ray</x:Key></x:Reference>

  <x:Reference>__ReferenceID1<x:Key>Bill</x:Key></x:Reference>

</FlowSwitch>

Persisted Data

Because of substantial changes in the instance schema and logic, you cannot migrated persisted data from .NET Framework 4 Beta 2 to RTM.

To upgrade from .NET Framework 4 Beta 2 to RTM, discard any existing instances and resubmit data. Alternatively, install the RTM version on a separate physical or virtual computer and target a different database than you used for Beta 2.

Literal<T> expressions

Literal expressions are represented in workflow by using the System.Activities.Expressions.Literal<T> activity class. In the .NET Framework 4 Beta 2, you could create an instance of Literal<T> by using any type for T. However, in the RTM version, you cannot use reference types, except strings.

This change was made because users incorrectly thought that creating a Literal<T> with a new reference type created that new reference type for each instance of the workflow. Disallowing literal reference types eliminates this confusion.

A Literal<List<String>> supports only value types and the immutable type System.String. The type System.Collections.Generic.List`1<System.String> cannot be used as a literal.

In Beta 2, the following workflow definition would run without error. In RTM, it causes a validation error:

List<string> names = new List<string> {"Frank", "Joe", "Bob" };

Variable<List<string>> nameVar = new Variable<List<string>> { Default = new Literal<List<string>>(names)};           

//Note: The following is the equivalent of the line above; the implicit cast creates a Literal<T> expression.

//Variable<List<string>> nameVar = new Variable<List<string>> { Default = names };

DelegateInArgument<string> name = new DelegateInArgument<string>();

Activity program = new Sequence

{

    Variables = { nameVar },

    Activities =

    {

        new AddToCollection<string> {

            Collection = new InArgument<ICollection<string>>(nameVar),

            Item = new InArgument<string>("Jim")},

        new ForEach<string>{

            Values = new InArgument<IEnumerable<string>>(nameVar),

            Body = new ActivityAction<string>{

                Argument = name,

                Handler = new WriteLine { Text = new InArgument<string>(name)}}}

    }

};

If you used reference types in Literal<T> expressions, you must use a different kind of expression to introduce the reference type into the workflow, such as the VisualBasicValue<T> and LambdaValue<T> classes. The following example shows how to use the VisualBasicValue<T> class.

Variable<List<string>> nameVar = new Variable<List<string>>{

    Default = new VisualBasicValue<List<string>>("New List(Of String)(New String() {\"Frank\", \"Joe\", \"Bob\"})")};

DelegateInArgument<string> name = new DelegateInArgument<string>();

Activity program =  new Sequence

{

    Variables = { nameVar },

    Activities =

    {

        new AddToCollection<string> {

            Collection = new InArgument<ICollection<string>>(nameVar),

            Item = new InArgument<string>("Jim")},

        new ForEach<string>{

            Values = new InArgument<IEnumerable<string>>(nameVar),

            Body = new ActivityAction<string>{

                Argument = name,

                Handler = new WriteLine { Text = new InArgument<string>(name)}}}

    }

};

TrackingRecord.EventTime property

The TrackingRecord.EventTime property in the System.Activities.Tracking namespace now has a value of type System.DateTime instead of type DateTimeOffset. This property stores the time in UTC when the TrackingRecord was emitted.

If you created a custom tracking participant that consumes TrackingRecord objects and accesses the EventTime property, you will have to change the type of your participant. If the logic in the tracking participant implementation assigns the EventTime property from the TrackingRecord, the location where the property is assigned will receive a DateTime type instead of a DateTimeOffset type.

Show:
© 2015 Microsoft