【问题标题】:Best work around to fix DateTimeOffset over WCF Data Service issue通过 WCF 数据服务问题修复 DateTimeOffset 的最佳解决方法
【发布时间】:2011-04-11 16:12:51
【问题描述】:

我尝试为实体框架模型创建一个 WCF 数据服务,该模型包含一些 DateTimeOffset 类型的属性。但是,WCF 数据服务不支持 DateTimeOffset 类型,因为我在谷歌搜索异常文本“'Task' 类型上的属性 'CreationTime' 的类型为 'DateTimeOffset' 类型,这不是受支持的原始类型。'。请参阅服务器日志有关更多详细信息。异常堆栈跟踪是:..."。

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

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

  2. 将数据库中的列类型保留为 DateTimeOffset,将该列映射到实体框架模型中的两个属性,一个 DateTime 和一个整数类型的附加“Offset”属性。

我真的不喜欢这些方法中的任何一种。有没有人找到解决此问题的好方法?

【问题讨论】:

  • 您是否考虑过提供自己的序列化器/反序列化器?

标签: entity-framework wcf service


【解决方案1】:

只需将 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;
...

【讨论】:

    【解决方案2】:

    使用反射有点小题大做,但是在应用程序启动中添加以下内容(我使用 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());
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 我认为在你投反对票时添加一个表扬是合适的。我不确定我是否在这里看到了这个问题,因为这个解决方案已经在我们的 5000 多次部署中投入生产了近两年,并且仍然没有问题。
        猜你喜欢
        • 1970-01-01
        • 2019-09-20
        • 1970-01-01
        • 2010-11-15
        • 2012-12-06
        • 2010-10-09
        • 1970-01-01
        • 2018-09-28
        • 1970-01-01
        相关资源
        最近更新 更多