views:

263

answers:

2

We are trying to force our datetime objects in c# to serialize using a different format than the default. We don't want to include milliseconds. The SortableDateTimePattern and the UniversalSortableDateTimePattern is read-only.

+1  A: 

Assuming you're talking about DateTime instances in a DataContract being sent by the server, I don't think there's a straightforward way to do this. The patterns you mention aren't used (if they were, you could just hack the shared pattern instance via reflection for a gross-but-easy solution). The DataContractSerializer ultimately delegates the task to the internal XsdDateTime.ToString() method, which is hardcoded to always emit the fractional seconds if they're nonzero.

It's not elegant, but taking advantage of the hardcoded behavior might be the simplest solution: just copy all your DateTimes, resetting the milliseconds to zero before they leave the server.

Alternatively, you're left with hooking up a custom IDispatchMessageFormatter or IDispatchMessageInspector on the affected operations. Neither is a walk in the park if you want them to be generic and easy to hook up.

Just curious- do you have a misbehaving client that doesn't understand the fractional seconds?

nitzmahone
A: 

I figured out a few ways to handle this problem. The more complicated methods involve hooking of a custom MessageFormatter Endpoint.

We found a simple way to to this.

the Fraction of seconds are only generated if the datetime object has them.

What we did:

We created a static on propertychange event handler that uses reflection to detect datetime datatypes. When found we recreate the datetime without the fractions of seconds. In our case we didn't care about seconds at all. We wire the event up in a partial class constructor. Thats it.

Of course

public static class DateTimeSecondCatcher
{
    PropertyInfo dateTimePropertyInfo = sender.GetType().GetProperty(e.PropertyName);
        if ((dateTimePropertyInfo != null) && (dateTimePropertyInfo.PropertyType == typeof(DateTime)))
        {

            DateTime dteValue = (DateTime)dateTimePropertyInfo.GetValue(sender, null);
            if (dteValue.Millisecond > 0)
            {
                dateTimePropertyInfo.SetValue(sender, new DateTime(dteValue.Year,dteValue.Month,dteValue.Day, dteValue.Hour,dteValue.Minute,dteValue.Second,0,dteValue.Kind), null);
            }
        }

}


// This code goes in the partial class constructor
this.PropertyChanged += new PropertyChangedEventHandler(DateTimeSecondCatcher.OnPropertyChanged);
Coach David