首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ServiceContract对名称空间的定义如何影响功能

ServiceContract对名称空间的定义如何影响功能
EN

Stack Overflow用户
提问于 2018-11-29 11:32:54
回答 1查看 47关注 0票数 0

我有一个这样的ServiceContract:

代码语言:javascript
复制
  [ServiceContract]
  public interface IHttpsServer
  {
    [OperationContract] 
    [XmlSerializerFormat]
    void Post(SomeEvent e);
  }

事件定义如下:

代码语言:javascript
复制
  [Serializable]
  [XmlType(Namespace = "")]
  public class SomeEvent 
  {
    [XmlAttribute("flag")]
    public bool m_bFlag;

    [XmlElement("Name")]
    public string m_strName;
    ...
  }

此服务由ServiceHost托管,并带有“BasicHttpBinding”。

我没在做什么:

  1. 启动web服务
  2. 在客户端应用程序上添加对正在运行的web服务的引用
  3. 启动客户端并将SomeEvent发送到服务器。

此时我遇到了一个问题--Post函数将被调用,但是SomeEvent是空的(所有可空字段都是null)。

但是,如果我为ServiceContrat ([ServiceContract(Namespace = "")])提供了一个空的命名空间,那么它可以正常工作。为什么会发生这种事?

更新:

我已经执行了几次检查,任何有奇怪结果的检查:

  1. 当由ServiceContract和SomeEvent ([ServiceContract(Namespace = "http://anynamespace")][XmlType(Namespace = "http://othernamespace")])定义名称空间时,它就能正常工作。
  2. 当名称空间仅由ServiceContract ([ServiceContract(Namespace = "http://anynamespace")][XmlType(Namespace = "")])定义时,则无法工作。
  3. 当两个([ServiceContract(Namespace = "")][XmlType(Namespace = "")])都定义了一个空的命名空间时,它就可以正常工作。
  4. 当ServiceContract有一个空的名称空间,但是为SomeEvent ([ServiceContract(Namespace = "")][XmlType(Namespace = "http://othernamespace")])定义了一个名称空间时,它就可以正常工作了。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-30 15:48:32

嗯,我想,我已经找到了这种行为的原因。

首先,我实现了IDispatchMessageInspector。这使我有可能追踪客户的请求。客户端的请求如下所示:

代码语言:javascript
复制
+       request {<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">https://localhost/</To>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IHttpsServer/Post</Action>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Post xmlns="http://tempuri.org/">
      <xml flag="true">
        <Name>John</Name>
      </xml>
    </Post>
  </s:Body>
</s:Envelope>}  System.ServiceModel.Channels.Message {System.ServiceModel.Channels.BufferedMessage}

过了一段时间,我注意到,为Post节点定义了默认名称空间,没有为'xml‘节点定义名称空间。因此,本例中的xmlxmlns="http://tempuri.org/"的一部分,而不是它定义的空名称空间。

为了检查我的建议,我生成了客户机代码,并手动将XmlType属性添加到SomeEvent的声明中

代码语言:javascript
复制
  [System.Xml.Serialization.XmlType(Namespace = "")]

在进行此更改之后,我得到了以下请求:

代码语言:javascript
复制
+       request {<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">https://localhost/</To>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IHttpsServer/Post</Action>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Post xmlns="http://tempuri.org/">
      <xml flag="true">
        <Name xmlns="">John</Name>
      </xml>
    </Post>
  </s:Body>
</s:Envelope>}  System.ServiceModel.Channels.Message {System.ServiceModel.Channels.BufferedMessage}

( Name节点定义了默认命名空间)。

在那之后我的服务很好。

我对问题原因的建议

如果我为事件[XmlType(Namespace = "")]public class SomeEvent {...}定义了空的命名空间,那么在生成客户端代码时,属性XmlType将被跳过。当发送请求时,描述事件的xml被放置到ServiceContract的命名空间中。之后,WCF无法反序列化事件。

因此,这个问题有两个解决方案。

  1. 避免使用空命名空间的事件(参见用例2)。
  2. 为事件[XmlType(Namespace = "")]public partial class SomeEvent {}添加部分类
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53538084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档