Почему сгенерированный прокси-код создает новый класс, когда MessageContract находится в моей службе WCF? - PullRequest
2 голосов
/ 24 мая 2010

Я создал две службы WCF (Shipping & PDFGenerator).Они оба вместе с моим ClientApp совместно используют сборку с именем Kyle.Common.Contracts.В этой сборке у меня есть три класса:

namespace Kyle.Common.Contracts
{
    [MessageContract]
    public class PDFResponse
    {
        [MessageHeader]
        public string fileName { get; set; }
        [MessageBodyMember]
        public System.IO.Stream fileStream { get; set; }
    }

    [MessageContract]
    public class PDFRequest
    {
        [MessageHeader]
        public Enums.PDFDocumentNameEnum docType { get; set; }
        [MessageHeader]
        public int? pk { get; set; }
        [MessageHeader]
        public string[] emailAddress { get; set; }
        [MessageBodyMember]
        public Kyle.Common.Contracts.TrackItResult[] trackItResults { get; set; }
    }

    [DataContract(Name = "TrackResult", Namespace = "http://kyle")]
    public class TrackResult
    {
        [DataMember]
        public int SeqNum { get; set; }
        [DataMember]
        public int ShipmentID { get; set; }
        [DataMember]
        public string StoreNum { get; set; }
    }
}

Мой PDFGenerator ServiceContract выглядит следующим образом:

namespace Kyle.WCF.PDFDocs
{
    [ServiceContract(Namespace="http://kyle")]
    public interface IPDFDocsService
    {
        [OperationContract]
        PDFResponse GeneratePDF(PDFRequest request);

        [OperationContract]
        void GeneratePDFAsync(Kyle.Common.Contracts.Enums.PDFDocumentNameEnum docType, int? pk, string[] emailAddress);

        [OperationContract]
        Kyle.Common.Contracts.TrackResult[] Test();
    }
}

Если я закомментирую заглушку GeneratePDF, прокси, сгенерированный VS2010, поймет, что Test возвращаетмассив Kyle.Common.Contracts.TrackResult.Однако если я оставлю GeneratePDF там, прокси-сервер откажется использовать Kyle.Common.Contracts.TrackResult и вместо этого создаст новый класс ClientApp.PDFDocServices.TrackResult и использует его в качестве возвращаемого типа Test.

Есть ли способ заставить генератор прокси использовать Kyle.Common.Contracts.TrackResult всякий раз, когда я использую MessageContract?Возможно, есть лучший метод для использования потока и имени файла в качестве возвращаемого типа?

Я просто не хочу создавать метод Copy для копирования из ClientApp.PDFDocServices.TrackResult в Kyle.Common.Contracts.TrackResult, поскольку они должны быть точно такого же класса.

Ответы [ 3 ]

2 голосов
/ 26 мая 2010

После долгих копаний я понимаю, что это был Enum, который "сломал" его.Это связано с тем, как DataContractSerializer работает против XmlSerializer.Короче говоря, решением было превратить Enum в обнуляемый.

[MessageContract]
public class PDFRequest
{
    [MessageHeader]
    public Enums.PDFDocumentNameEnum? docType { get; set; }
    [MessageHeader]
    public int? pk { get; set; }
    [MessageHeader]
    public string[] emailAddress { get; set; }
    [MessageBodyMember]
    public Kyle.Common.Contracts.TrackItResult[] trackItResults { get; set; }
}
2 голосов
/ 11 июня 2015

Я столкнулся с той же проблемой (MessageContract + enums), и ваш пост помог мне. Действительно, если вы явно установите для полей enum значение nullable, это сработает. Проблема заключается в том, что при использовании перечислений WCF использует сериализатор XML, который не может отличить ноль от пустой строки.

Существует подробное объяснение этого поведения здесь одним из реальных членов команды WCF.

В случае документа / литерала при использовании пустых сообщений WCF возвращается к XmlSerializer при обработке перечислимых типов. ... XmlSerializer рассматривает null как отсутствующий по умолчанию ... мы встречаем схему без nillable = "true" ... Логика обнаружения для типов значений в настоящее время обрабатывает только примитивные типы значений, но не проверяет перечисления.

Другими словами, WCF не любит перечисления ... Но, эй, это работает, вам просто нужно знать об этом!

1 голос
/ 24 мая 2010

Вы можете указать Visual Studio повторно использовать классы из ссылочных сборок.Поэтому, если ваш тестовый проект имеет ссылку на сборку Kyle.Common.Contracts, он должен повторно использовать определенные в ней типы, а не добавлять новые прокси-классы на стороне клиента.

Переключатель для включения этого находится наAdvanced страница в диалоговом окне Add Service Reference - она ​​должна быть включена по умолчанию:

альтернативный текст http://i48.tinypic.com/281d3m1.png

Убедитесь, что ваш проект

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