Справочник службы WCF для DateTimeOffset? не использовать тип FCL

Я использую .NET 4.5.1 для своей службы WCF и .NET 4.0 для клиентского приложения Windows.

В Контракте данных есть DataMember типа DateTimeOffset? (с нулевым значением DataTimeOffset).

Когда я добавляю ссылку на службу в службу WCF, она считает, что DateTimeOffset? является сложным типом. Другими словами, он не считает это System.DateTimeOffset?, он считает это ServiceReference1.DataTimeOffset?

Как это исправить?

Вот что я пробовал до сих пор:

  • Создайте наиболее простое примерное решение, демонстрирующее это. К сожалению, я не мог воссоздать проблему, поэтому она должна быть чем-то уникальным для моей конфигурации.

  • Аннотировать класс DataContract с помощью [KnownType(typeof(DateTimeOffset?))]. К сожалению, это ничего не делало.

  • Проверьте "Типы повторного использования в ссылочных сборках". Это привело к тому, что объект "ServiceReference1" вообще не был доступен в Консольном приложении.

У кого-нибудь есть другие идеи о том, как это исправить?

Спасибо.

Ответ 1

Вы на правильном пути с KnownType.

Чтобы достичь своей цели, вы не можете использовать "Добавить ссылку на службу". Вместо этого ваше клиентское приложение должно иметь ссылку на ваш класс [ServiceContract]. Затем вы можете напрямую вызвать службу с помощью ChannelFactory.

Код сервера:

using System;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace Server
{
    public class Service : IService
    {
        public ReturnContract GetOffset()
        {
            return new ReturnContract { Offset = new DateTimeOffset(DateTime.Now) };
        }
    }

    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        ReturnContract GetOffset();
    }

    [DataContract]
    [KnownType(typeof(DateTimeOffset))]
    public class ReturnContract
    {
        [DataMember]
        public DateTimeOffset? Offset { get; set; }
    }
}

Код клиента

using Server;
using System;
using System.ServiceModel;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            var cf = new ChannelFactory<Server.IService>("endpoint");
            var service = cf.CreateChannel();
            ReturnContract c = service.GetOffset();

            Console.WriteLine(c.Offset);
            Console.ReadLine();
        }
    }
}

Ответ 2

Это может произойти, если проекты ваших контрактов с данными не построены должным образом или вы не хотите повторно использовать библиотеку, которая содержит DateTimeOffset и Nullable<> - mscorlib и/или проект контракта с вашими данными.

Поэтому убедитесь, что:

  • Целевая структура проекта для контрактов данных не больше, чем .NET Framework 4.0. Потому что .NET Framework не пересылается совместимым. Ссылка на него из проекта клиента не должна быть отмечена предупреждающим знаком:
    Сломанная ссылка в клиентской библиотеке
  • Проект контрактов данных построен
  • Оба mscorlib и ваш проект контрактов с данными находятся в списке ссылок, типы которых необходимо повторно использовать или вы выбираете тип повторного использования во всех ссылочных сборках: Диалоговое окно конфигурации служебной ссылки

Ответ 3

Вам определенно нужно будет указать "Типы повторного использования в ссылочных сборках", чтобы получить поведение, которое вы ищете.

Затем возникает вопрос, что приводит к тому, что ваш сервис не будет доступен в вашем приложении консоли. Я бы предположил, что ваше решение не совсем правильно настроено, но мне нужно больше деталей. Экранный снимок решения, содержащего консольное приложение, был бы идеальным.

Вы добавили ссылку на службу в проект приложения консоли или другой проект?