Ответ Webservice превращается в параметр ref при использовании MessageContract

Я определил следующий интерфейс

[ServiceContract]
public interface IHealthProducts
{
    [OperationContract()]
    ResponseClass OrderSelfSignedHealthCertificate();
}

Который возвращает следующий тип

[MessageContract]
public class ResponseClass
{
    [MessageBodyMember]
    public string AnimalSpeciesCode
    {
        get;
        set;
    }

    [MessageBodyMember]
    public int VBN
    {
        get;
        set;
    }
}

Я ожидал, что сгенерированный код клиента будет предоставлять метод OrderSelfSignedHealthCertificate следующим образом:

HealthProductsClient client = new HealthProductsClient();
ResponseClass response = client.OrderSelfSignedHealthCertificate();

Вместо этого свойства ResponseClass не оборачиваются в ResponseClass, а отображаются следующим образом:

string OrderSelfSignedHealthCertificate(out int VBN)

Когда я обмениваю MessageContract для атрибута DataContract и MessageBodyMember для атрибута DataMember, я получаю ожидаемое поведение (тип ответа ResponseClass). Однако мне нужен MessageContract, потому что мне нужно поместить некоторые свойства в заголовок SOAP.

Я делаю что-то неправильно? Это нормальное поведение? Как получить тип возврата ResponseClass при использовании MessageContract?

Любая помощь с благодарностью.

3 ответа

Решение

Когда ваш [MessageContract] содержит более одного [MessageBodyMember]то WCF вернет первое как возвращаемое значение из вызова сервиса (AnimalSpeciesCode в вашем случае), а все остальные возвращаются как out или же ref paraemters.

Вы можете решить это, имея только один [MessageBodyMember] в вашем контракте на сообщения, который включает в себя все элементы, которые вам нужно вернуть, примерно так:

[DataContract]
class CompoundData
{
    public string AnimalSpeciesCode { get; set; }
    public int VBN { get; set; }
}

[MessageContract]
public class ResponseClass
{
    [MessageBodyMember]
    public CompoundData Payload { get; set; }
}

В этом случае CompoundData должно быть значением, возвращаемым из вашего сервисного вызова - содержащим оба необходимых элемента.

Спасибо Марк, что сделал это. Я создал общий класс ResponseWrapper для инкапсуляции возвращаемых типов:

[MessageContract(WrapperNamespace = "http://mynamespace.com")]
public class ResponseWrapper<T>
{
    [MessageBodyMember(Namespace = "http://mynamespace.com")]
    public T Response
    {
        get;
        set;
    }
}

Я определил возвращаемый тип OrderSelfSignedHealthCertificate как

ResponseWrapper<ResponseClass> OrderSelfSignedHealthCertificate();

В моем коде клиента это перевести на

ResponseClass OrderSelfSignedHealthCertificate(); 

Что я и хотел. Спасибо!

Я разместил продолжение этого вопроса здесь. Универсальные возвращаемые типы не имеют правильного имени при использовании MessageContract.

Другие вопросы по тегам