Cla*_*unt 3 c# wcf serialization deserialization
我有一种情况,我们正在连接到 SOAP 服务。
我们得到的响应如下所示:
<SomeObject>
<item1>1</item1>
<thing1>2</thing1>
<arrayItem><foo>text</foo></arrayItem>
<arrayItem><foo>text1</foo></arrayItem>
<arrayItem><foo>text2</foo></arrayItem>
</SomeObject>
Run Code Online (Sandbox Code Playgroud)
我需要复制该响应的输出。我一直遇到的问题是<arrayItem>'s 被封装了<arrayItemList>,我真的需要把's 去掉<arrayItemList>。
有谁知道我可以在 WCF 对象上放什么来正确序列化/反序列化我们接收的对象?
编辑
我正在处理的对象是这样的:
[DataContract]
public class SomeObject
{
[DataMember(Order = 0)]
public string item1 {get;set;}
[DataMember(Order = 1)]
public string thing1 {get;set;}
[DataMember(Order = 2)]
public List<arrayItem> {get;set;}
}
[DataContract]
public class arrayItem
{
[DataMember]
public string foo {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我无法找到一个很好的解决方案。但是,我确实找到了一个可行的解决方案。
警告 - 如果可能,您应该尝试修改 WSDL 以防止需要此解决方案。这更像是一个 hack 然后是一个建议的解决方案,但会在紧要关头工作。
解决方案是实现 IClientMessageInspector 和 IEndpointBehavior。这些接口允许访问原始文本请求和响应。这些允许在消息发送到服务或由 WCF 反序列化之前对其进行修改。下面是我的实现和一个允许修改我需要的消息的自定义类。
public class MyService : IClientMessageInspector
{
public void DoWork()
{
// Do some stuff
}
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
string message = reply.ToString();
// Load the reply message in DOM for easier modification
XmlDocument doc = new XmlDocument();
doc.Load(reply.GetReaderAtBodyContents());
// Perform the modification
MessageHelper.FixArrays(doc);
// Create New Message
XmlNodeReader reader = new XmlNodeReader(doc.DocumentElement);
Message newMsg = Message.CreateMessage(reply.Version, reply.Headers.Action, reader);
// Preserve the headers of the original message
if (reply.Headers.Any())
newMsg.Headers.CopyHeaderFrom(reply, 0);
foreach (string propertyKey in reply.Properties.Keys)
{
newMsg.Properties.Add(propertyKey, reply.Properties[propertyKey]);
}
// Close the original message and return new message
reply.Close();
reply = newMsg;
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
return null;
}
}
public static class MessageHelper
{
public static void FixArrays(XmlDocument doc)
{
// Arrearage
WrapElement(doc, "foo", "arrayItem", "http://url.com/namespace/foo");
}
private static void WrapElement(XmlDocument doc, string elementName, string wrapperName, string nameSpace)
{
var names = new XmlNamespaceManager(doc.NameTable);
names.AddNamespace("a", nameSpace);
var Nodes = doc.SelectNodes("//a:" + elementName, names);
if (Nodes.Count > 0)
{
var newBorrower = doc.CreateElement(Nodes.Item(0).Prefix, wrapperName, Nodes.Item(0).NamespaceURI);
foreach (XmlElement node in Nodes)
{
newBorrower.AppendChild(node.Clone());
}
Nodes.Item(0).ParentNode.ReplaceChild(newBorrower, Nodes.Item(0));
for (int i = 1; i <= Nodes.Count - 1; i++)
{
Nodes.Item(i).ParentNode.RemoveChild(Nodes.Item(i));
}
}
}
private static void WrapRenameElement(XmlDocument doc, string newName, string elementName, string wrapperName, string nameSpace, string newNamespace)
{
var names = new XmlNamespaceManager(doc.NameTable);
names.AddNamespace("a", nameSpace);
names.AddNamespace("b", newNamespace);
var Nodes = doc.SelectNodes("//a:" + elementName + "/..", names);
foreach (XmlElement parent in Nodes)
{
var newBorrower = doc.CreateElement(parent.Prefix, wrapperName, parent.NamespaceURI);
foreach (XmlElement child in parent.ChildNodes)
{
if (child.LocalName == elementName)
{
var newNode = RenameNode(child.Clone(), newNamespace, newName);
parent.RemoveChild(child);
newBorrower.AppendChild(newNode);
}
}
if (newBorrower.ChildNodes.Count > 0)
parent.AppendChild(newBorrower);
}
}
private static void WrapRenameElement(XmlDocument doc, string newName, string elementName, string wrapperName, string nameSpace)
{
var names = new XmlNamespaceManager(doc.NameTable);
names.AddNamespace("a", nameSpace);
var Nodes = doc.SelectNodes("//a:" + elementName + "/..", names);
foreach (XmlElement parent in Nodes)
{
var newBorrower = doc.CreateElement(parent.Prefix, wrapperName, parent.NamespaceURI);
foreach (XmlElement child in parent.ChildNodes)
{
if (child.LocalName == elementName)
{
var newNode = RenameNode(child.Clone(), nameSpace, newName);
parent.RemoveChild(child);
newBorrower.AppendChild(newNode);
}
}
if (newBorrower.ChildNodes.Count > 0)
parent.AppendChild(newBorrower);
}
}
public static XmlNode RenameNode(XmlNode node, string namespaceURI, string qualifiedName)
{
if (node.NodeType == XmlNodeType.Element)
{
XmlElement oldElement = (XmlElement)node;
XmlElement newElement =
node.OwnerDocument.CreateElement(qualifiedName, namespaceURI);
while (oldElement.HasAttributes)
{
newElement.SetAttributeNode(oldElement.RemoveAttributeNode(oldElement.Attributes[0]));
}
while (oldElement.HasChildNodes)
{
newElement.AppendChild(oldElement.FirstChild);
}
if (oldElement.ParentNode != null)
{
oldElement.ParentNode.ReplaceChild(newElement, oldElement);
}
return newElement;
}
else
{
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
就像我说的,它并不漂亮,它本质上是一个 hack,但是这个解决方案可以解决我遇到的问题。我希望没有其他人需要处理这个问题,但如果他们这样做了,我希望这会有所帮助。
| 归档时间: |
|
| 查看次数: |
6872 次 |
| 最近记录: |