4.0 Beta2 to RC/RTM WCF/WF List of Breaking changes
This list covers known breaking changes between 4.0 Beta2 and RC/RTM WCF & WF Framework.
Summary of Breaking Changes
FlowChart Designer produces FlowSwitch<T> instead of FlowSwitch
Description: In Beta2 the FlowSwitch item in the activities toolbox produces a non-generic FlowSwitch. Post Beta2, it produces a FlowSwitch<T>. The reason for the change is that non-generic FlowSwitch (used in beta2 and earlier) only allowed to switch on strings (e.g. all keys in the cases needed to be strings) while FlowSwitch<T> allows to switch on any type of T.
Customer impact: Flowcharts that use a FlowSwitch and have been authored using the WF designer in Beta2 or earlier won’t load in the WF designer post beta2.
Mitigation: If you’re using FlowSwitch in a Flowchart workflow using Beta2 (or pre-Beta2 builds), you will need to hand edit the Flowchart XAML and add x:TypeArguments="x:String" to the FlowSwitch node as shown in the snippet below (highlighted code):
Beta2
<FlowSwitch 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>
RC
<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>
Compiler error(s) encountered while processing an expression
Description: Post Beta2 we added additional validation to ensure the user is targeting the right SKU and that all assemblies referenced in a workflow expression are referenced by the project and only use assemblies supported in the targeted SKU (i.e. Client or Full).
Customer impact: Hit a similar exception as below - Items highlighted will differ based on your project and naming, etc.
'Workflow1': The private implementation of activity '1: Workflow1' has the following validation error: Compiler error(s) encountered processing expression "GetType(Microsoft.Xrm.Sdk.Entity).Assembly.FullName".
Type 'Microsoft.Xrm.Sdk.Entity' is not defined.
Mitigation: If you hit the above exception, please ensure you are targeting the right SKU and that all assemblies referenced in the workflow expression are referenced by the project and only use assemblies supported in the targeted SKU.
Reference Types in Literal <T> Expressions
Description: Literal expressions are represented in WF using the Literal<T> activity. In Beta2 any type could be used with this expression. In RC It is invalid to initialize Literal<T> with an instance of a reference type. String is the only exception to this rule. The motivation for the change was that users erroneously thought that creating a Literal<T> with a new reference type created the new reference type for each instance of the workflow. Disallowing “Literal” reference types eliminates this confusion. In Beta2 the following workflow definition would run without error. In RC it will receive a validation error:
'Literal<List<String>>': Literal only supports value types and the immutable type System.String. The type System.Collections.Generic.List`1[System.String] cannot be used as a literal.
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 to 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)}}}
}
};
Customer Impact: Customers who have used reference types in Literal<T> expressions will need to use a different kind of expression to introduce the reference type into the workflow. For example VisualBasicValue<T> or LambdaValue<T>.
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)}}}
}
};
Mitigation (if any): n/a
IPC channel security descriptor change (Remoting)
Description: In Beta2, if a user in UAC – User Access Control with administrator privileges creates a named pipe in the IPC (Inter-process Communication) channel then that user’s SID is ACL-ed (Access Control List). However, that enables the user in UAC to access the named pipe when that user loses the administrator privileges.
Post Beta2, we provide users with an API to be able to change the security descriptor in the named pipe so the previous values of security descriptor can be restored. This API helps users to make their apps more secure and consists of a new IPCChannel constructor that takes an extra fourth argument with a custom security descriptor to override the default one:
public IpcChannel(IDictionary properties, IClientChannelSinkProvider clientSinkProvider,
IServerChannelSinkProvider serverSinkProvider, CommonSecurityDescriptor securityDescriptor)
{
}
Customer Impact: Customers that create IPC channel in Beta2, will notice the change of the default security descriptor if their security descriptor must be different than the provided one in beta2. However, in post Beta2, you can now specify your own security descriptor using the new added constructor.
Mitigation (if any): We have provided the API described above that will allow users to set their own security descriptor.
Type change for the EventTime property in the TrackingRecord API
Description: In Beta2, the EventTime property within System.Activities.Tracking.TrackingRecord was of the type System.DateTimeOffset, post Beta2 the type was changed to System.DateTime. The EventTime property stores the time in UTC when the TrackingRecord was emitted.
public abstract class TrackingRecord {
…
public System.DateTime EventTime { get; }
…
}
Customer Impact: Customers who have created a custom tracking participant which consumes TrackingRecord objects and access the EventTime property will need to change the type. If the logic within the tracking participant implementation assigns the EventTime property from the TrackingRecord, the place where the property is assigned will receive a DateTime type instead of DateTimeOffset.
Mitigation (if any): none.
New Persistence impacts
Description: Due to large changes in the instance schema and logic, it is not possible to migrated persisted data from Beta 2 to RC.
Customer Impact: To upgrade from Beta 2 to RC/RTM, discard any existing instances and resubmit data. Alternatively, install RC on separate physical or virtual machines and target a different database than used for Beta 2.
Mitigation (if any): none.
-- Khalid Mouss.
Comments
- Anonymous
March 14, 2010
nice improvements.... but need to improve the vb expresstions used in workflows....because string comparisons in vb expresstions often produce wrong results i.e i have declare a variable in my class as following: string productTyp="SDE" when i used it in workflow vb expresstions like that myClassObjet.productType.Equals("SDE")=true the result produced here is false. Why these expresstions are not kept in c# ?