gpt4 book ai didi

wcf - NET WCF客户端中如何忽略DateTime的时区?

转载 作者:行者123 更新时间:2023-12-04 04:14:05 27 4
gpt4 key购买 nike

WCF客户端正在从Java Web服务接收Date值,其中以XML发送给客户端的日期为:

<sampleDate>2010-05-10+14:00</sampleDate>

现在,接收到该日期的WCF客户端处于时区(+08:00),并且当该客户端反序列化Date值时,它将转换为以下DateTime值:

2010-05-09 18:00 +08:00

但是,我们想忽略从服务器发送的+14:00,以便客户端中的序列化Date值为:

2010-05-10

请注意,+ 14:00不一致,可能是+10:00,+ 11:00等,因此无法在客户端使用DateTime转换来获取所需的日期值。

如何在WCF中轻松实现?

提前致谢。

更新

正确的WCF解决方案是否将实现IClientMessageFormatter?

解决方案

对我来说,最干净的解决方案是按照上面的建议实现IClientMessageFormatter。这是一个例子:

C#代码
public class ClientMessageFormatter : IClientMessageFormatter
{
IClientMessageFormatter original;

public ClientMessageFormatter(IClientMessageFormatter actual)
{
this.original = actual;
}

public void RemoveTimeZone(XmlNodeList nodeList)
{
if (nodeList != null)
{
foreach (XmlNode node in nodeList)
{
node.InnerText = Regex.Replace(node.InnerText, @"[\+\-]\d\d:\d\d", "");
}
}
}

#region IDispatchMessageFormatter Members

public object DeserializeReply(Message message, object[] parameters)
{
Message newMessage = null;
Message tempMessage;
MessageBuffer buffer;
MemoryStream ms;
XmlDocument doc;
XmlDictionaryReader reader;
XmlReader xr;
XmlWriter xw;

try
{
buffer = message.CreateBufferedCopy(int.MaxValue);
tempMessage = buffer.CreateMessage();
reader = tempMessage.GetReaderAtBodyContents();

if (reader != null)
{
doc = new XmlDocument();
doc.Load(reader);
reader.Close();

if (doc.DocumentElement != null)
{
/* enables switching between responses */
switch (doc.DocumentElement.LocalName)
{
case "sampleRootElement":
RemoveTimeZone(doc.DocumentElement.SelectNodes("childElement1/childElement2"));
break;
}
}

ms = new MemoryStream();
xw = XmlWriter.Create(ms);
doc.Save(xw);
xw.Flush();
xw.Close();

ms.Position = 0;
xr = XmlReader.Create(ms);

newMessage = Message.CreateMessage(message.Version, null, xr);
newMessage.Headers.CopyHeadersFrom(message);
newMessage.Properties.CopyProperties(message.Properties);
}
}
catch (Exception ex)
{
throw ex;
}

return original.DeserializeReply((newMessage != null) ? newMessage : message, parameters);
}

public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
{
return original.SerializeRequest(messageVersion, parameters);
}

#endregion

}

public class ClientOperationBehavior : IOperationBehavior
{

public void AddBindingParameters(OperationDescription description, BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
{
IClientMessageFormatter currentFormatter = proxy.Formatter;
proxy.Formatter = new ClientMessageFormatter(currentFormatter);
}

public void ApplyDispatchBehavior(OperationDescription description, DispatchOperation operation)
{
}

public void Validate(OperationDescription description)
{
}
}

public class ClientEndpointBehavior : IEndpointBehavior
{

#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
foreach (OperationDescription operation in endpoint.Contract.Operations)
{
operation.Behaviors.Add(new ClientOperationBehavior());
}
}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}

public void Validate(ServiceEndpoint endpoint)
{
}
#endregion
}

public class ClientBehaviorExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get
{
return typeof(ClientEndpointBehavior);
}
}

protected override object CreateBehavior()
{
return new ClientEndpointBehavior();
}
}

App.config/Web.config

然后,客户端配置文件将使用上述格式化程序,如下所示:
<system.serviceModel>
....
....
<extensions>
<behaviorExtensions>
<add name="clientMessageFormatterBehavior" type="..." />
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="clientMessageFormatterBehavior">
<clientMessageFormatterBehavior />
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="https://www.domain.com/service" behaviorConfiguration="clientMessageFormatterBehavior" .... />
</client>
....
....
</system.serviceModel>

引用

http://blogs.msdn.com/b/stcheng/archive/2009/02/21/wcf-how-to-inspect-and-modify-wcf-message-via-custom-messageinspector.aspx

最佳答案

嗨,我改良后的通用解决方案

public static class TimeZoneMessageHelper
{
public static Message RemoveTimeZone(this Message message)
{
try
{
using (XmlDictionaryReader messageBodyReader = message.GetReaderAtBodyContents())
{
XmlDocument xmlDocument = new XmlDocument();
Message returnMessage = null;
xmlDocument.Load(messageBodyReader);

RemoveTimeZone(xmlDocument);

StringBuilder stringBuilder = new StringBuilder();
using(XmlWriter xmlWriter = XmlWriter.Create(stringBuilder))
{
xmlDocument.Save(xmlWriter);
}

// do not dispose to early
XmlReader resultMessageBodyReader = XmlReader.Create(new StringReader(stringBuilder.ToString()));

returnMessage = Message.CreateMessage(message.Version, null, resultMessageBodyReader);
returnMessage.Headers.CopyHeadersFrom(message);
returnMessage.Properties.CopyProperties(message.Properties);

return returnMessage;
}
}
}

private static void RemoveTimeZone(XmlNode xmlNode)
{
if (xmlNode.ChildNodes.Count == 0)
{
RemoveTimeZoneCore(xmlNode);
}
else
{
foreach(XmlNode node in xmlNode.ChildNodes)
RemoveTimeZone(node);
}
}

public static void RemoveTimeZoneCore(XmlNode xmlNode)
{
if (xmlNode != null)
{
if (Regex.IsMatch(xmlNode.InnerText, @"^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d\d)?(\+|-)\d\d:\d\d$", RegexOptions.Compiled))
{
xmlNode.InnerText = xmlNode.InnerText.Substring(0, xmlNode.InnerText.Length - 6);
}
}
}
}

public class RemoveTimeZoneClientMessageFormatter : IClientMessageFormatter
{
private readonly IClientMessageFormatter original;

public RemoveTimeZoneClientMessageFormatter(IClientMessageFormatter original)
{
this.original = original;
}

#region Implementation of IClientMessageFormatter

public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
{
return original.SerializeRequest(messageVersion, parameters).RemoveTimeZone();
}

public object DeserializeReply(Message message, object[] parameters)
{
return original.DeserializeReply(message.RemoveTimeZone() ?? message, parameters);
}

#endregion
}

public class RemoveTimeZoneDispatchMessageFormatter : IDispatchMessageFormatter
{
private readonly IDispatchMessageFormatter original;

public RemoveTimeZoneDispatchMessageFormatter(IDispatchMessageFormatter original)
{
this.original = original;
}

#region Implementation of IDispatchMessageFormatter

public void DeserializeRequest(Message message, object[] parameters)
{
original.DeserializeRequest(message.RemoveTimeZone() ?? message, parameters);
}

public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
return original.SerializeReply(messageVersion, parameters, result).RemoveTimeZone();
}

#endregion
}

public class RemoveTimeZoneEndpointBehavior : IEndpointBehavior
{

#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
foreach (OperationDescription operation in endpoint.Contract.Operations)
{
operation.Behaviors.Add(new RemoveTimeZoneOperationBehavior());
}
}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
foreach(OperationDescription operation in endpoint.Contract.Operations)
{
operation.Behaviors.Add(new RemoveTimeZoneOperationBehavior());
}
}

public void Validate(ServiceEndpoint endpoint)
{
}
#endregion
}

public class RemoveTimeZoneOperationBehavior : IOperationBehavior
{

public void AddBindingParameters(OperationDescription description, BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
{
proxy.Formatter = new RemoveTimeZoneClientMessageFormatter(proxy.Formatter);
}

public void ApplyDispatchBehavior(OperationDescription description, DispatchOperation operation)
{
operation.Formatter = new RemoveTimeZoneDispatchMessageFormatter(operation.Formatter);
}

public void Validate(OperationDescription description)
{
}
}

public class RemoveTimeZoneExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get
{
return typeof(RemoveTimeZoneEndpointBehavior);
}
}

protected override object CreateBehavior()
{
return new RemoveTimeZoneEndpointBehavior();
}
}\

关于wcf - NET WCF客户端中如何忽略DateTime的时区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3067650/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com