如何更改 svcutil.exe 生成的 类 中的 xsd:date 格式
How to change xsd:date format in svcutil.exe generated classes
我从 .wsdl 文件生成了 C# 类,它可以工作。但我有以下问题。响应中的服务格式 xsd:date
类型不正确。示例:
<date xsi:type="xsd:date">2016-01-27 14:20:30</date>
但应该是其中之一:
<date xsi:type="xsd:date">2016-01-27</date>
<date xsi:type="xsd:dateTime">2016-01-27T14:20:30</date>
因此我得到了例外
Unhandled Exception: System.ServiceModel.CommunicationException: Error
in deserializing body of reply message for operation 'createVacature'.
---> System.InvalidOperationException: There is an error in XML document (2, 646). ---> System.FormatException: String was not
recognized as a valid DateTime.
如何覆盖日期解析?或者有什么其他方法可以修复吗?在没有 svcutil.exe 的情况下手动实施所有这些将是矫枉过正的。
这是我的解决方案。我在解析之前拦截服务响应并手动编辑它。
这是日期修复功能:
public class MessageDateFixer : IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
return null;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
XmlDocument document = new XmlDocument();
MemoryStream memoryStream = new MemoryStream();
XmlWriter xmlWriter = XmlWriter.Create(memoryStream);
reply.WriteMessage(xmlWriter);
xmlWriter.Flush();
memoryStream.Position = 0;
document.Load(memoryStream);
FixMessage(document);
memoryStream.SetLength(0);
xmlWriter = XmlWriter.Create(memoryStream);
document.WriteTo(xmlWriter);
xmlWriter.Flush();
memoryStream.Position = 0;
XmlReader xmlReader = XmlReader.Create(memoryStream);
reply = Message.CreateMessage(xmlReader, int.MaxValue, reply.Version);
}
private static void FixMessage(XmlDocument document)
{
FixAllNodes(document.ChildNodes);
}
private static void FixAllNodes(XmlNodeList list)
{
foreach (XmlNode node in list)
{
FixNode(node);
}
}
private static void FixNode(XmlNode node)
{
if (node.Attributes != null &&
node.Attributes["xsi:type"] != null)
{
if (node.Attributes["xsi:type"].Value == "xsd:date")
{
node.Attributes["xsi:type"].Value = "xsd:dateTime";
node.InnerXml = node.InnerXml.Replace(" ", "T");
}
}
FixAllNodes(node.ChildNodes);
}
}
这里是辅助class:
public class DateFixerBehavior : IEndpointBehavior
{
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new MessageDateFixer());
}
public void Validate(ServiceEndpoint endpoint)
{
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
}
用法如下:
PosterToolClient poster = new PosterToolClient();
poster.Endpoint.Behaviors.Add(new DateFixerBehavior());
我从 .wsdl 文件生成了 C# 类,它可以工作。但我有以下问题。响应中的服务格式 xsd:date
类型不正确。示例:
<date xsi:type="xsd:date">2016-01-27 14:20:30</date>
但应该是其中之一:
<date xsi:type="xsd:date">2016-01-27</date>
<date xsi:type="xsd:dateTime">2016-01-27T14:20:30</date>
因此我得到了例外
Unhandled Exception: System.ServiceModel.CommunicationException: Error in deserializing body of reply message for operation 'createVacature'. ---> System.InvalidOperationException: There is an error in XML document (2, 646). ---> System.FormatException: String was not recognized as a valid DateTime.
如何覆盖日期解析?或者有什么其他方法可以修复吗?在没有 svcutil.exe 的情况下手动实施所有这些将是矫枉过正的。
这是我的解决方案。我在解析之前拦截服务响应并手动编辑它。
这是日期修复功能:
public class MessageDateFixer : IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
return null;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
XmlDocument document = new XmlDocument();
MemoryStream memoryStream = new MemoryStream();
XmlWriter xmlWriter = XmlWriter.Create(memoryStream);
reply.WriteMessage(xmlWriter);
xmlWriter.Flush();
memoryStream.Position = 0;
document.Load(memoryStream);
FixMessage(document);
memoryStream.SetLength(0);
xmlWriter = XmlWriter.Create(memoryStream);
document.WriteTo(xmlWriter);
xmlWriter.Flush();
memoryStream.Position = 0;
XmlReader xmlReader = XmlReader.Create(memoryStream);
reply = Message.CreateMessage(xmlReader, int.MaxValue, reply.Version);
}
private static void FixMessage(XmlDocument document)
{
FixAllNodes(document.ChildNodes);
}
private static void FixAllNodes(XmlNodeList list)
{
foreach (XmlNode node in list)
{
FixNode(node);
}
}
private static void FixNode(XmlNode node)
{
if (node.Attributes != null &&
node.Attributes["xsi:type"] != null)
{
if (node.Attributes["xsi:type"].Value == "xsd:date")
{
node.Attributes["xsi:type"].Value = "xsd:dateTime";
node.InnerXml = node.InnerXml.Replace(" ", "T");
}
}
FixAllNodes(node.ChildNodes);
}
}
这里是辅助class:
public class DateFixerBehavior : IEndpointBehavior
{
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new MessageDateFixer());
}
public void Validate(ServiceEndpoint endpoint)
{
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
}
用法如下:
PosterToolClient poster = new PosterToolClient();
poster.Endpoint.Behaviors.Add(new DateFixerBehavior());