最好通过修复DateTimeOffset而不是WCF数据服务问题

时间:2010-09-13 13:22:38

标签: entity-framework wcf service

我尝试为Entity Framework模型创建一个WCF数据服务,该模型包含DateTimeOffeset类型的一些属性。但是,WCF数据服务不支持类型DateTimeOffset,因为我在搜索异常文本后发现“类型'Task'上的属性'CreationTime'是'DateTimeOffset'类型,它不是受支持的基本类型。'。请参阅服务器日志有关更多详细信息,异常堆栈跟踪是:...“。

我现在正在考虑解决这个问题的不同方法,包括:

  1. 将类型更改为可以映射到数据库中的DateTime的内容(最差解决方案)

  2. 将列类型保留为数据库中的DateTimeOffset,将列映射到Entity Framework模型中的两个属性,一个DateTime和另一个类型为integer的“Offset”属性。

  3. 我真的不喜欢这些方法。有没有人找到了解决这个问题的好方法?

4 个答案:

答案 0 :(得分:2)

只需将DateTimeOffset类型作为KnownType添加到包含CreationTime属性的EF数据协定中,如http://msdn.microsoft.com/en-us/library/ms730167.aspx中所述。

DateTimeOffset是实际作为基元处理的复杂.NET类型之一,除了默认情况下它没有注册为序列化程序的KnownType。所以你需要手动完成。

您的代码可能如下所示:

[DataContract]
[KnownType(typeof(DateTimeOffset))]
public class Task
{
    [DataMember]
    private DateTimeOffset CreationTime;
...

答案 1 :(得分:1)

这是一个使用反射的黑客攻击,但是在应用程序启动时使用以下内容(我使用WebActivator)到目前为止使用的是2011年10月的CTP。

var primitiveResourceTypeMapType = typeof(ResourceType).Assembly.GetType("System.Data.Services.Providers.PrimitiveResourceTypeMap");
Debug.Assert(primitiveResourceTypeMapType != null);
var builtInTypesMappingField = primitiveResourceTypeMapType.GetField("builtInTypesMapping", BindingFlags.NonPublic | BindingFlags.Static);
Debug.Assert(builtInTypesMappingField != null);

var existingMap = ((KeyValuePair<Type, string>[])builtInTypesMappingField.GetValue(null)).ToList();
existingMap.Add(new KeyValuePair<Type, string>(typeof(DateTimeOffset), "Edm.DateTimeOffset"));
existingMap.Add(new KeyValuePair<Type, string>(typeof(DateTimeOffset?), "Edm.DateTimeOffset"));
builtInTypesMappingField.SetValue(null, existingMap.ToArray());

答案 2 :(得分:-1)

我建议从您的服务中传递包含TimeZone.GetUtcOffset Method return的字段,然后计算该字段与客户端偏移之间的差异,然后从返回的DateTime中添加/减去该差异。

答案 3 :(得分:-1)

您遇到的问题是因为XmlSerializer无法序列化DataTimeOffset。但是,如果您使用DataContractSerializer,它将处理DateTimeOffset就好了。不需要自定义序列化程序或额外的箍来跳过。

这就是我所做的,并且没有任何问题。