WCF DataContractSerializer не получает атрибуты контракта ... почему бы и нет? - PullRequest
4 голосов
/ 16 июля 2009

У меня есть следующий тип, который я использую как контракт сообщения в WCF:

[MessageContract(IsWrapped = true, 
                 WrapperNamespace = "http://example.com/services", 
                 WrapperName = "EchoRequest")]
public class EchoRequest
{
    public EchoRequest() { }
    public EchoRequest(String value)
    {
        Value = value;
    }

    [MessageBodyMember(Name = "Value", 
                       Namespace = "http://example.com/services", 
                       Order = 0)]
    public String Value { get; set; }
}

Когда я генерирую прокси для этого типа, используя svcutil.exe , я получаю клиента, который может взаимодействовать с сервисом, который его размещает, с пространствами имен XML на элементах, правильными согласно сообщению Атрибуты договора.

Когда я использую Message.CreateMessage(...) для его экземпляра, пространства имен возвращаются к значениям по умолчанию (http://schemas.datacontract.org/2004/07/...). Когда я использую экземпляр DataContractSerializer, происходит то же самое. Я пытаюсь передать пространство имен конструктор DataContractSerializer, и в пространство имен включается только оболочка:

var requestMessage = new EchoRequest("hello, world!");
var serializer = new DataContractSerializer(typeof(EchoRequest), 
                                            "EchoRequest", 
                                            "http://example.com/services");
var stream = new MemoryStream();
serializer.WriteObject(stream, requestMessage);
var data = Encoding.UTF8.GetString(stream.ToArray());

При этом «данные»:

<EchoRequest xmlns="http://example.com/services"
             xmlns:a="http://schemas.datacontract.org/2004/07/TestClient"
             xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <a:Value>hello, world!</a:Value>
</EchoRequest>

Почему DataContractSerializer игнорирует атрибуты MessageContract? Как svcutil получает эту работу?

1 Ответ

5 голосов
/ 16 июля 2009

Это потому, что контракты сообщений не являются контрактами данных, контракты данных используют разные атрибуты для маркировки своих классов. Попробуйте использовать конвертер типизированных сообщений;

EchoRequest echoRequest = new EchoRequest{ value = "Hello" };

TypedMessageConverter echoMessageConverter = TypedMessageConverter.Create(
                 typeof(echoRequest),
                 "YourActionNameHere",
                 "http://example.com/services");
Message request = echoMessageConverter.ToMessage(
    echoRequest,MessageVersion.Soap11);

После этого вы получите сообщение, готовое к отправке, и сможете извлечь тело запроса, если вам нужно.

...