Extending Commerce OrderForm

We have extended the OrderForm with a Strongly-Typed property ("OrderType") via the OrderObjectMappings.xml file and run the tool to update the scripts and OrderForm table.

We have created an inherited Commerce Order Form Class which inherits from the Microsoft.CommerceServer.Runtime.Orders.OrderForm Class. The skeleton of the class is as follows:

protected CommerceOrderForm(SerializationInfo info, StreamingContext context): base(info, context)

{

m_dtmOrderDate = info.GetDateTime("OrderDate");

try

{

m_strOrderType = info.GetString("OrderType");

}

catch (SerializationException)

{

m_strOrderType = string.Empty;

}

}

When existing objects are hydrated, they of course do NOT have a property named "OrderType". Therefore, a SerializationException is thrown. To address that issue, we use a try..catch to set the the new property to a default value.

What is the correct way to handle extensions (Properties) to Commerce Server and properly hyrdrate existing objects that do not have the new Property so that a SerializationException is not thrown?

1) Use Try..Catch?

2) Use the .GetEnumerator on the SerializationInfo object and loop through each name-value pair?

3) Use Class Versioning to determine which properties are mapped based on the class properties?

Thanks for the help..

Erl

[4542 byte] By [ErlEgestad] at [2008-2-25]
# 1
In our samples we've recommended option #1. Option #2 can be an interesting approach. This avoids the exception from being raised at all but if there are too many properties in the class probably it might be expensive to enumerate through all the properties and look for the specific property. I don't understand option#3 that well. Can you provide me little more details here.
VKUMAR-MSFT at 2007-9-4 > top of Msdn Tech,Commerce Server,Commerce Server 2007...
# 2
Option 3 refers to using a weakly type property to track the Class Version. Then increment this value when a a property is added so that when serialization occurs, the class nows whether to attempt to read a property that was just added.
ErlEgestad at 2007-9-4 > top of Msdn Tech,Commerce Server,Commerce Server 2007...
# 3
This option looks good to me. This avoids the exception without perf hit.
VKUMAR-MSFT at 2007-9-4 > top of Msdn Tech,Commerce Server,Commerce Server 2007...
# 4

If you end up going with option one this method will help with parsing the serialization stream:

public static T GetValue<T>(SerializationInfo info, string name)

{

Type ReturnValueType = typeof(T);

T ReturnValue = default(T);

try

{

ReturnValue = (T)info.GetValue(name, ReturnValueType);

}

catch (SerializationException exception)

{

Log(48, TraceEventType.Error, null, null, exception.Message); // EVENT 48

}

catch (InvalidCastException exception)

{

Log(49, TraceEventType.Error, null, null, exception.Message); // EVENT 49

}

return ReturnValue;

}

The main advantage here is that you can call this.propertyName = GetValue<DateTime>(info, "PropertyName") and keep your rountine clean. It could also be replaced with the second enumeration option to leverage the generics aspect.

As for option three it would really depend on if you are offering an optional property and if you can guarantee that in post-v1 instances of the object that it will have a value.

Cheers,
Colin

ColinBowern at 2007-9-4 > top of Msdn Tech,Commerce Server,Commerce Server 2007...