Клиент WCF получает значение Date от веб-службы Java, где дата, отправленная клиенту в 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