WCF DataContractSerializer不';无法获取合同属性。。。为什么不呢?

WCF DataContractSerializer不';无法获取合同属性。。。为什么不呢?,wcf,datacontractserializer,datacontract,messagecontract,Wcf,Datacontractserializer,Datacontract,Messagecontract,我将以下类型用作WCF中的消息协定: [MessageContract(IsWrapped = true, WrapperNamespace = "http://example.com/services", WrapperName = "EchoRequest")] public class EchoRequest { public EchoRequest() { } public EchoRequest(S

我将以下类型用作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(…)
时,名称空间将恢复为默认值()。当我使用
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());
此时,“数据”为:


你好,世界!

为什么
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);

然后,您将收到一条准备就绪的消息,如果需要,可以将请求正文拉出。

是的,就是这样!书籍和文档在如何处理消息契约方面显得相当零碎,这是我第一次遇到TypedMessageConverter。谢谢如果消息协定的成员使用XmlSerialization属性而不是DataContract属性(它们可以从DataContractSerializer无法表示的WSDL/XSD生成),请使用
TypedMessageConverter.Create
的重载,该重载接受
XmlSerializerFormatAttribute
,指示它改为使用XmlSerialization。使用EchoRequest类型创建代理类不是更容易吗。您可以将这个类再次命名为EchoRequest,并在上面的原始类can-be-datacontract中将其定义为MessageContract。这是双重定义,但对我来说很好。谢谢你问这个问题!我正好遇到了这个问题,几乎立刻就发现了你的问题。
EchoRequest echoRequest = new EchoRequest{ value = "Hello" };

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