WCF DataContractSerializer не собирает атрибуты контракта ... почему бы и нет?
-
16-09-2019 - |
Вопрос
У меня есть следующий тип, который я использую в качестве договора сообщения в 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 получить эту работу?
Решение
Это потому, что договоры сообщений не являются контрактами на данные, контракты на данные используют разные атрибуты, чтобы отметить их классы. Попробуйте использовать напечатанный конвертер сообщений;
EchoRequest echoRequest = new EchoRequest{ value = "Hello" };
TypedMessageConverter echoMessageConverter = TypedMessageConverter.Create(
typeof(echoRequest),
"YourActionNameHere",
"http://example.com/services");
Message request = echoMessageConverter.ToMessage(
echoRequest,MessageVersion.Soap11);
Затем у вас будет сообщение, готовое к работе, и сможет вытащить тело запроса, если вам нужно.