WCF DataContractSerializer 不获取契约属性...为什么不呢?

发布于 2024-07-27 19:46:05 字数 1761 浏览 6 评论 0原文

我有以下类型,在 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 如何完成这项工作?

I have the following type which I use as a message contract in 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; }
}

When I generate a proxy to this type using svcutil.exe, I get a client which is able to communicate to a service which hosts it, with the XML namespaces on the elements correct according to the Message Contract attributes.

When I use Message.CreateMessage(...) on an instance of it, the namespaces revert to the default (http://schemas.datacontract.org/2004/07/...). When I use an instance of DataContractSerializer, the same thing happens. I try to pass a namespace to the DataContractSerializer constructor, and only the wrapper gets included in the namespace:

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());

At this, "data" is:

<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>

Why does the DataContractSerializer appear to ignore the MessageContract attributes? How does svcutil get this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑看君怀她人 2024-08-03 19:46:05

这是因为消息契约不是数据契约,数据契约使用不同的属性来标记它们的类。 尝试使用类型化消息转换器;

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

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

然后,您将收到一条已准备就绪的消息,并且可以根据需要提取请求正文。

It's because message contracts are not data contracts, data contracts use different attributes to mark their classes. Try using a typed message converter;

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

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

You'll then have a message all ready to go and can pull the request body out if you need to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文