C# 如何在svcutil.exe生成的类中更改xsd:date格式
我从.wsdl文件生成了C#类,它可以正常工作。但我有以下问题。响应中的服务格式C# 如何在svcutil.exe生成的类中更改xsd:date格式,c#,xmlserializer,svcutil.exe,formatexception,service-model,C#,Xmlserializer,Svcutil.exe,Formatexception,Service Model,我从.wsdl文件生成了C#类,它可以正常工作。但我有以下问题。响应中的服务格式xsd:date类型不正确。例如: <date xsi:type="xsd:date">2016-01-27 14:20:30</date> 2016-01-27 14:20:30 但它应该是其中之一: <date xsi:type="xsd:date">2016-01-27</date> <date xsi:type="xsd:dateTime">
xsd:date
类型不正确。例如:
<date xsi:type="xsd:date">2016-01-27 14:20:30</date>
2016-01-27 14:20:30
但它应该是其中之一:
<date xsi:type="xsd:date">2016-01-27</date>
<date xsi:type="xsd:dateTime">2016-01-27T14:20:30</date>
2016-01-27
2016-01-27T14:20:30
正因为如此,我得到了一个例外
未处理的异常:System.ServiceModel.CommunicationException:错误
在反序列化操作“CreateVacation”的回复消息正文中。
--->System.InvalidOperationException:XML文档(2646)中存在错误。-->System.FormatException:未找到字符串
被识别为有效的日期时间
如何覆盖日期解析?或者用其他方法来修复它?在没有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);
}
}
这是辅助课:
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中承诺了日期,但生成了狗屎。若您不能在服务器端更改任何内容,那个么您的方法是在生成的代码中找到这个字段(类似于
publicdatetime date{get{}set{}
),并用类型字符串替换类型DateTime。您的客户机将接受响应,但您必须将date的这种“不错的”ODBC规范格式转换为DateTime(当然,如果您真的需要日期),这是我尝试的第一件事,但它无论如何被解析为DateTime。我发现了一个有趣的解决方案,可以在解析xml之前拦截xml,并手动修复日期格式,目前仍在研究中,看起来很有希望。