WCF DataContractSerializer nimmt keine Vertragsattribute auf ... warum nicht?
-
16-09-2019 - |
Frage
Ich habe den folgenden Typ, den ich als Nachrichtenvertrag in WCF verwende:
[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; }
}
Wenn ich einen Proxy für diesen Typ generiere svcutil.exe, Ich erhalte einen Kunden, der in der Lage ist, mit einem Dienst zu kommunizieren, der ihn mit den XML -Namespaces in den Elementen gemäß den Nachrichtenvertragsattributen korrigiert.
Wenn ich benutze Message.CreateMessage(...)
In einer Instanz davon kehren die Namespaces zur Standardeinstellung zurück (http://schemas.datacontract.org/2004/07/ ...). Wenn ich eine Instanz von benutze DataContractSerializer
, Das Gleiche passiert. Ich versuche, einen Namespace an die zu übergeben DataContractSerializer
Konstruktor, und nur der Wrapper wird in den Namespace enthalten:
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());
In diesem Fall ist "Daten":
<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>
Warum das DataContractSerializer
scheinen die zu ignorieren MessageContract
Attribute? Wie geht es svcutil diese Arbeit bekommen?
Lösung
Dies liegt daran, dass Nachrichtenverträge keine Datenverträge sind. Datenverträge verwenden unterschiedliche Attribute, um ihre Klassen zu markieren. Versuchen Sie, einen typisierten Nachrichtenkonverter zu verwenden.
EchoRequest echoRequest = new EchoRequest{ value = "Hello" };
TypedMessageConverter echoMessageConverter = TypedMessageConverter.Create(
typeof(echoRequest),
"YourActionNameHere",
"http://example.com/services");
Message request = echoMessageConverter.ToMessage(
echoRequest,MessageVersion.Soap11);
Sie haben dann eine Nachricht, die alle bereit sind und können den Anforderungskörper herausziehen, wenn Sie müssen.