Ответ веб-службы превращается в параметр 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?

Любая помощь очень ценится.


person Soeteman    schedule 03.03.2010    source источник


Ответы (2)


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

Вы можете решить эту проблему, имея только один [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 должно быть возвращаемым значением из вашего вызова службы, содержащим оба нужных вам элемента.

person marc_s    schedule 03.03.2010

Спасибо Марк, это сделало это. Я создал общий класс 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(); 

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

person Soeteman    schedule 05.03.2010
comment
Пожалуйста, обновите свой вопрос вместо того, чтобы добавлять ответы, если вы действительно не нашли ответ. - person John Saunders; 05.03.2010