2010-09-13 3 views
9

Я пытаюсь создать службу данных WCF для модели Entity Framework, которая содержит некоторые атрибуты типа DateTimeOffeset. Однако служба данных WCF не поддерживает тип DateTimeOffset, как я узнал после того, как он перешел в текст исключения. «Свойство CreationTime» в типе «Задача» имеет тип «DateTimeOffset», который не является поддерживаемым примитивным типом ». См. Журналы сервера для более подробной информации. Трассировка стека исключений: ... ".Лучшая работа по исправлению DateTimeOffset по вызову службы данных WCF

Я сейчас рассматривает различные подходы к решению этой проблемы в том числе:

  1. изменить тип на то, что может быть сопоставлен с DateTime в базе данных (худшее решение)

  2. Оставьте колонку введите в базу данных DateTimeOffset, сопоставьте столбец с двумя атрибутами в модели Entity Framework, один DateTime и дополнительный атрибут «Offset» типа integer.

Мне действительно не нравится любой из этих подходов. Кто-нибудь нашел хорошую работу, чтобы решить эту проблему?

+0

Вы изучили предоставление собственного сериализатора/десериализатора? – louisgab

ответ

2

Просто добавьте тип DateTimeOffset как KnownType к контракту данных EF, который содержит свойство CreationTime, как описано в http://msdn.microsoft.com/en-us/library/ms730167.aspx.

DateTimeOffset - один из сложных типов .NET, который фактически обрабатывается как примитив, за исключением того, что он не зарегистрирован по умолчанию в качестве KnownType для сериализаторов. Поэтому вам нужно сделать это вручную.

Ваш код может выглядеть следующим образом:

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

Предлагаю передать поле из вашей службы, которое содержит TimeZone.GetUtcOffset Method return, а затем вычислить разницу между этим и смещением клиента и затем добавить/вычесть это отличие от возвращаемого DateTime.

1

Это немного рубить с помощью отражения, но положить следующее в приложении запуска (я использовал WebActivator) до сих пор работал для меня с помощью октября 2011 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()); 
-1

Проблема, которую вы видите, состоит в том, что XmlSerializer не может сериализовать DataTimeOffset. Однако, если вы используете DataContractSerializer, он отлично обрабатывает DateTimeOffset. Нет необходимости в создании пользовательских сериализаторов или дополнительных обручей.

Это то, что я сделал, и у меня нет проблем.

+0

Я думаю, что уместно добавить оценку, когда вы проголосуете. Не уверен, что я вижу проблему здесь, так как это решение уже почти 5000 лет выпускается в нашей компании более 5000 лет и по-прежнему остается без проблем. – SonOfPirate

Смежные вопросы