Лучшее решение для устранения проблемы DateTimeOffset over WCF Data Service - PullRequest
9 голосов
/ 13 сентября 2010

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

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

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

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

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

Ответы [ 4 ]

2 голосов
/ 25 сентября 2011

Просто добавьте тип 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 голос
/ 15 декабря 2011

Это что-то вроде хака, использующего рефлексию, но размещение следующего при запуске приложения (я использовал WebActivator ) до сих пор работало для меня с использованием CTP-версии октября 2011 года.

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());
0 голосов
/ 26 января 2012

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

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

0 голосов
/ 04 апреля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...