我正在实现一个WCF服务来替换现有的SOAP服务。访问此服务的客户端无法更改(除配置指向新服务器外)。
当响应名为Ping的方法时,原始服务器响应:
使用WCF重新创建方法,我已设法尽可能接近:
当我从C#控制台应用程序调用原始服务时,会正确填充PingResult。只需将端点的地址更改为我的新服务并重新运行,服务就会返回新的响应,但PingResult为空。我唯一可以看到原始和我的不同之处是PingResult节点上的“ns1”前缀。我猜这是在客户端绊倒反序列化。
所以我的问题是,如何从PingResult中删除ns1前缀?
感谢。
答案 0 :(得分:1)
你可以试试这个,我从来没有改变过消息,所以我不确定它是否完全像这样,但我已经这样做来记录消息。
实现消息监听器。您有机会处理ExitRequestedHandler
方法,您可以访问该消息并更改消息。
然后使用属性BeforeSendReply
[MessageListenerBehavior]
执行using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace YourNamespace
{
public class MessageListenerBehavior : Attribute, IDispatchMessageInspector, IServiceBehavior
{
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
Message msg = reply.CreateBufferedCopy(int.MaxValue).CreateMessage();
try
{
//Setup StringWriter to use as input for our StreamWriter
//This is needed in order to capture the body of the message, because the body is streamed.
using (StringWriter stringWriter = new StringWriter())
using (XmlWriter xmlTextWriter = XmlWriter.Create(stringWriter))
{
msg.WriteMessage(xmlTextWriter);
xmlTextWriter.Flush();
xmlTextWriter.Close();
string thexml = stringWriter.ToString();
XDocument doc = XDocument.Parse(thexml);
// alter the doc here...........
Message newMsg = Message.CreateMessage(MessageVersion.Soap11, "http://..something", doc.ToString());
reply = newMsg;
}
catch (Exception ex) { //handle it }
}
public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
foreach (var endpoint in dispatcher.Endpoints)
{
endpoint.DispatchRuntime.MessageInspectors.Add(new MessageListenerBehavior());
}
}
}
public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
//throw new NotImplementedException();
}
}
public class WcfMessgeLoggerExtension : BehaviorExtensionElement
{
public override Type BehaviorType
{
get
{
return typeof(MessageListenerBehavior);
}
}
protected override object CreateBehavior()
{
return new MessageListenerBehavior();
}
}
}
时我不知道Message.CreateMessage
参数在回复中的重要程度,但您可以阅读有关如何构建其值的信息:
更新
我在Action
config:
system.serviceModel
...