我有一个这样的ServiceContract:
[ServiceContract]
public interface IHttpsServer
{
[OperationContract]
[XmlSerializerFormat]
void Post(SomeEvent e);
}
事件定义如下:
[Serializable]
[XmlType(Namespace = "")]
public class SomeEvent
{
[XmlAttribute("flag")]
public bool m_bFlag;
[XmlElement("Name")]
public string m_strName;
...
}
此服务由ServiceHost
通过'BasicHttpBinding'托管。
我在做什么:
这时我遇到了一个问题-将调用后函数,但是SomeEvent为空(所有可为空的字段均为null
)。
但是,如果我对ServiceContrat([ServiceContract(Namespace = "")]
)使用了一个空名称空间,那么它可以正常工作。
为什么会这样?
更新:
我已经执行了几项检查,结果都奇怪:
[ServiceContract(Namespace = "http://anynamespace")]
和[XmlType(Namespace = "http://othernamespace")]
)定义名称空间时,它正常工作。[ServiceContract(Namespace = "http://anynamespace")]
和[XmlType(Namespace = "")]
)定义名称空间,则不起作用。[ServiceContract(Namespace = "")]
和[XmlType(Namespace = "")]
都定义了一个空的命名空间时,它工作正常。[ServiceContract(Namespace = "")]
和[XmlType(Namespace = "http://othernamespace")]
),则工作正常。答案 0 :(得分:0)
好吧,我想,我已经找到了这种现象的原因。
首先,我实现了IDispatchMessageInspector
。这使我可以跟踪来自客户端的请求。
来自客户端的请求如下所示:
+ 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'节点定义任何名称空间。因此,我们拥有的是该示例中的xml
是xmlns="http://tempuri.org/"
的一部分,而不是它定义的空名称空间。
要检查我的建议,我生成了客户端代码,并在XmlType
的声明中手动添加了SomeEvent
属性:
[System.Xml.Serialization.XmlType(Namespace = "")]
更改之后,我得到了以下请求:
+ 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无法反序列化事件。
因此,该问题有两种解决方案:
[XmlType(Namespace = "")]public partial class SomeEvent {}
添加部分类