WCF&;IXmlSerializable:根元素在响应中被替换
我们在这里为“协议”定制了XML序列化: 使用标准.NETWCF&;IXmlSerializable:根元素在响应中被替换,wcf,serialization,Wcf,Serialization,我们在这里为“协议”定制了XML序列化: 使用标准.NETXmlSerializer时,一切都很好: <?xml version="1.0" encoding="utf-16"?> <axf version="1.0.0" createdAt="2011-10-20T13:11:40" xmlns="http://schemas.***.ru/axf/axf-1.0.0"> <itineraries> <!-- --> </
XmlSerializer
时,一切都很好:
<?xml version="1.0" encoding="utf-16"?>
<axf version="1.0.0" createdAt="2011-10-20T13:11:40" xmlns="http://schemas.***.ru/axf/axf-1.0.0">
<itineraries>
<!-- -->
</itineraries>
</axf>
发送到客户端的实际XML文档如下所示:
<GetItinerariesResult version="1.0.0" createdAt="2011-10-20T13:17:50" xmlns="http://tempuri.org/">
<itineraries xmlns="http://schemas.***.ru/axf/axf-1.0.0">
<!-- rest is fine, serialization code does work -->
如何弯曲WCF以按原样发送根元素,而不是将其替换为自己的根元素?默认情况下,操作响应包装在操作名称中。但是,您可以在操作定义中使用
MessageContract
来使用“unwrapped”响应,如下所示。如果您查看Fiddler中请求的响应主体,您将看到它与序列化中的响应主体完全相同
public class StackOverflow_7836645
{
[XmlRoot("axf", Namespace = Axf10Namespace)]
public class AxfDocument : IXmlSerializable
{
public const string Axf10Namespace = "http://schemas.something.ru/axf/axf-1.0.0";
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
}
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("intineraries", Axf10Namespace);
writer.WriteElementString("item", Axf10Namespace, "one value");
writer.WriteElementString("item", Axf10Namespace, "another value");
writer.WriteEndElement();
}
}
[MessageContract(IsWrapped = false)]
public class OperationResponse
{
[MessageBodyMember(Name = "axf", Namespace = AxfDocument.Axf10Namespace)]
public AxfDocument axf;
}
[ServiceContract]
public interface ITest
{
[OperationContract]
OperationResponse GetAxf();
}
public class Service : ITest
{
public OperationResponse GetAxf()
{
return new OperationResponse { axf = new AxfDocument() };
}
}
public static void Test()
{
Console.WriteLine("Serialization");
MemoryStream ms = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(AxfDocument));
xs.Serialize(ms, new AxfDocument());
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
Console.WriteLine();
Console.WriteLine("Service");
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
host.Open();
Console.WriteLine("Host opened");
ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
ITest proxy = factory.CreateChannel();
Console.WriteLine(proxy.GetAxf());
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
公共类堆栈溢出\u 7836645
{
[XmlRoot(“axf”,名称空间=Axf10Namespace)]
公共类AxfDocument:IXmlSerializable
{
公用常量字符串Axf10Namespace=”http://schemas.something.ru/axf/axf-1.0.0";
公共XmlSchema GetSchema()
{
返回null;
}
公共void ReadXml(XmlReader)
{
}
public void WriteXml(XmlWriter)
{
writer.writeStarteElement(“intinaries”,AXF10名称空间);
WriteElementString(“项”,AXF10名称空间,“一个值”);
WriteElementString(“项”,AXF10名称空间,“另一个值”);
writer.writeedelement();
}
}
[MessageContract(IsWrapped=false)]
公共类操作响应
{
[MessageBodyMember(Name=“axf”,Namespace=AxfDocument.Axf10Namespace)]
公共axf文档axf;
}
[服务合同]
公共接口测试
{
[经营合同]
操作响应GetAxf();
}
公共类服务:ITest
{
公共操作响应GetAxf()
{
返回新操作响应{axf=new AxfDocument()};
}
}
公共静态无效测试()
{
Console.WriteLine(“序列化”);
MemoryStream ms=新的MemoryStream();
XmlSerializer xs=新的XmlSerializer(typeof(AxfDocument));
序列化(ms,新的AxfDocument());
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray());
Console.WriteLine();
控制台写入线(“服务”);
string baseAddress=“http://“+Environment.MachineName+”:8000/服务”;
ServiceHost主机=新ServiceHost(类型(服务),新Uri(基地址));
AddServiceEndpoint(typeof(ITest),new BasicHttpBinding(),“”);
host.Open();
Console.WriteLine(“主机已打开”);
ChannelFactory工厂=新的ChannelFactory(新的BasicHttpBinding(),新的EndpointAddress(baseAddress));
ITest proxy=factory.CreateChannel();
Console.WriteLine(proxy.GetAxf());
((IClientChannel)代理).Close();
工厂关闭();
控制台。写入(“按ENTER键关闭主机”);
Console.ReadLine();
host.Close();
}
}
<GetItinerariesResult version="1.0.0" createdAt="2011-10-20T13:17:50" xmlns="http://tempuri.org/">
<itineraries xmlns="http://schemas.***.ru/axf/axf-1.0.0">
<!-- rest is fine, serialization code does work -->
public class StackOverflow_7836645
{
[XmlRoot("axf", Namespace = Axf10Namespace)]
public class AxfDocument : IXmlSerializable
{
public const string Axf10Namespace = "http://schemas.something.ru/axf/axf-1.0.0";
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
}
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("intineraries", Axf10Namespace);
writer.WriteElementString("item", Axf10Namespace, "one value");
writer.WriteElementString("item", Axf10Namespace, "another value");
writer.WriteEndElement();
}
}
[MessageContract(IsWrapped = false)]
public class OperationResponse
{
[MessageBodyMember(Name = "axf", Namespace = AxfDocument.Axf10Namespace)]
public AxfDocument axf;
}
[ServiceContract]
public interface ITest
{
[OperationContract]
OperationResponse GetAxf();
}
public class Service : ITest
{
public OperationResponse GetAxf()
{
return new OperationResponse { axf = new AxfDocument() };
}
}
public static void Test()
{
Console.WriteLine("Serialization");
MemoryStream ms = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(AxfDocument));
xs.Serialize(ms, new AxfDocument());
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
Console.WriteLine();
Console.WriteLine("Service");
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
host.Open();
Console.WriteLine("Host opened");
ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
ITest proxy = factory.CreateChannel();
Console.WriteLine(proxy.GetAxf());
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}