将命名空间添加到 MessageContract (WCF)
Adding a Namespace to a MessageContract (WCF)
我正在尝试创建要发送到 SAP 端点的 SOAP 消息,但是,我无法正确设置名称空间。我已经尝试了好几天并尝试了我在网上找到的许多建议,但 none 似乎有效。我希望你们中的一些人能帮助我。
这是我拥有的 C# 代码示例:
[ServiceContract]
[XmlSerializerFormat]
public interface IWcfClient
{
[OperationContract(IsOneWay = true)]
void SendUpdates(UpdateRequest request);
}
[MessageContract(IsWrapped = true, WrapperName = "MyRoot", WrapperNamespace = "myNamespace")]
public class UpdateRequest
{
[MessageBodyMember]
[XmlElement(ElementName = "updateType")]
public byte UpdateType { get; internal set; }
[MessageBodyMember]
[XmlElement(ElementName = "updateEntry")]
public UpdateEntry[] UpdateEntries { get; set; }
}
public class UpdateEntry
{
[XmlElement]
public string DeviceId { get; set; }
[XmlElement]
public DateTime LastSeen { get; set; }
}
这导致 SOAP 主体看起来像这样:
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyRoot xmlns="myNamespace">
<updateEntry>
<DeviceId>12345</DeviceId>
<LastSeen>2017-04-24T14:44:30.8030649Z</LastSeen>
</updateEntry>
<updateEntry>
<DeviceId>56789</DeviceId>
<LastSeen>2017-05-03T01:33:02.084Z</LastSeen>
</updateEntry>
<updateType>2</updateType>
</MyRoot>
</s:Body>
我想要实现的是向根添加另一个名称空间并让子元素使用该名称空间。最后,我正在寻找与此类似的结果 (mySecondNamespace):
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyRoot xmlns="myNamespace" xmlns:a="mySecondNamespace">
<a:updateEntry>
<a:DeviceId>12345</a:DeviceId>
<a:LastSeen>2017-04-24T14:44:30.8030649Z</a:LastSeen>
</a:updateEntry>
<a:updateEntry>
<a:DeviceId>56789</a:DeviceId>
<a:LastSeen>2017-05-03T01:33:02.084Z</a:LastSeen>
</a:updateEntry>
<a:updateType>2</a:updateType>
</MyRoot>
</s:Body>
我试过:
- 将 XmlRoot 添加到 MessageContract
- 将 XmlType 添加到 MessageContract
- 在 getter/setter 上使用 "XmlNamespaceDeclarations" 属性,其中新的命名空间被添加到命名空间集合中
- 在 OperationContract 上设置命名空间
但似乎没有任何效果。将命名空间添加到 XmlElement 似乎有效,但在这种情况下,命名空间不在根元素上,也不会传播到底层元素。有什么想法吗?
经过长时间的搜索,我终于找到了解决问题的方法。我必须做的是在 OperationContract 而不是接口本身上切换到 XmlSerializerFormat 并相应地更新合同:
[ServiceContract]
public interface IWcfClient
{
[XmlSerializerFormat]
[OperationContract(IsOneWay = true)]
void SendUpdates(UpdateRequest request);
}
[MessageContract(IsWrapped = false)]
public class UpdateRequest
{
[MessageBodyMember(Name="UpdateEntry")]
public UpdateEntry[] UpdateEntries { get; set; }
}
[Serializable]
[XmlType(Namespace = "myNamespace")]
public class UpdateEntry
{
[XmlElement(ElementName = "UpdateEntry", Order = 0)]
public Device[] DeviceInfo { get; set; }
[XmlElement(ElementName = "UpdateType", Order = 1)]
public byte UpdateType { get; set; }
}
[Serializable]
[XmlType(Namespace = "myNamespace")]
public class Device
{
[XmlElement(ElementName = "DeviceId", Order = 0)]
public string DeviceId { get; set; }
[XmlElement(ElementName = "LastSeen", Order = 1)]
public DateTime LastSeen { get; set; }
}
我正在尝试创建要发送到 SAP 端点的 SOAP 消息,但是,我无法正确设置名称空间。我已经尝试了好几天并尝试了我在网上找到的许多建议,但 none 似乎有效。我希望你们中的一些人能帮助我。
这是我拥有的 C# 代码示例:
[ServiceContract]
[XmlSerializerFormat]
public interface IWcfClient
{
[OperationContract(IsOneWay = true)]
void SendUpdates(UpdateRequest request);
}
[MessageContract(IsWrapped = true, WrapperName = "MyRoot", WrapperNamespace = "myNamespace")]
public class UpdateRequest
{
[MessageBodyMember]
[XmlElement(ElementName = "updateType")]
public byte UpdateType { get; internal set; }
[MessageBodyMember]
[XmlElement(ElementName = "updateEntry")]
public UpdateEntry[] UpdateEntries { get; set; }
}
public class UpdateEntry
{
[XmlElement]
public string DeviceId { get; set; }
[XmlElement]
public DateTime LastSeen { get; set; }
}
这导致 SOAP 主体看起来像这样:
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyRoot xmlns="myNamespace">
<updateEntry>
<DeviceId>12345</DeviceId>
<LastSeen>2017-04-24T14:44:30.8030649Z</LastSeen>
</updateEntry>
<updateEntry>
<DeviceId>56789</DeviceId>
<LastSeen>2017-05-03T01:33:02.084Z</LastSeen>
</updateEntry>
<updateType>2</updateType>
</MyRoot>
</s:Body>
我想要实现的是向根添加另一个名称空间并让子元素使用该名称空间。最后,我正在寻找与此类似的结果 (mySecondNamespace):
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyRoot xmlns="myNamespace" xmlns:a="mySecondNamespace">
<a:updateEntry>
<a:DeviceId>12345</a:DeviceId>
<a:LastSeen>2017-04-24T14:44:30.8030649Z</a:LastSeen>
</a:updateEntry>
<a:updateEntry>
<a:DeviceId>56789</a:DeviceId>
<a:LastSeen>2017-05-03T01:33:02.084Z</a:LastSeen>
</a:updateEntry>
<a:updateType>2</a:updateType>
</MyRoot>
</s:Body>
我试过:
- 将 XmlRoot 添加到 MessageContract
- 将 XmlType 添加到 MessageContract
- 在 getter/setter 上使用 "XmlNamespaceDeclarations" 属性,其中新的命名空间被添加到命名空间集合中
- 在 OperationContract 上设置命名空间
但似乎没有任何效果。将命名空间添加到 XmlElement 似乎有效,但在这种情况下,命名空间不在根元素上,也不会传播到底层元素。有什么想法吗?
经过长时间的搜索,我终于找到了解决问题的方法。我必须做的是在 OperationContract 而不是接口本身上切换到 XmlSerializerFormat 并相应地更新合同:
[ServiceContract]
public interface IWcfClient
{
[XmlSerializerFormat]
[OperationContract(IsOneWay = true)]
void SendUpdates(UpdateRequest request);
}
[MessageContract(IsWrapped = false)]
public class UpdateRequest
{
[MessageBodyMember(Name="UpdateEntry")]
public UpdateEntry[] UpdateEntries { get; set; }
}
[Serializable]
[XmlType(Namespace = "myNamespace")]
public class UpdateEntry
{
[XmlElement(ElementName = "UpdateEntry", Order = 0)]
public Device[] DeviceInfo { get; set; }
[XmlElement(ElementName = "UpdateType", Order = 1)]
public byte UpdateType { get; set; }
}
[Serializable]
[XmlType(Namespace = "myNamespace")]
public class Device
{
[XmlElement(ElementName = "DeviceId", Order = 0)]
public string DeviceId { get; set; }
[XmlElement(ElementName = "LastSeen", Order = 1)]
public DateTime LastSeen { get; set; }
}