Skip to content

Instantly share code, notes, and snippets.

@lontivero
Created December 14, 2013 03:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lontivero/7955440 to your computer and use it in GitHub Desktop.
Save lontivero/7955440 to your computer and use it in GitHub Desktop.
Shows how to manipulate raw wcf messages per operation.
using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using TinyClient.CustomerService;
namespace TinyClient
{
class Program
{
static void Main()
{
var customerService = new CustomerServiceClient();
customerService.Endpoint.Behaviors.Add(new ReplaceNameBehavior("GetData"));
customerService.Endpoint.Behaviors.Add(new AddZerosToIdsBehavior("GetDataById"));
var customerData1 = customerService.GetData();
var customerData2 = customerService.GetData2();
Console.WriteLine(customerData1.Name + " " + customerData1.Address);
Console.WriteLine(customerData2.Name + " " + customerData2.Address);
var customerData3 = customerService.GetDataById(12);
Console.WriteLine(customerData3.Name + " " + customerData3.Address);
}
}
public class ReplaceNameBehavior : TransformBehavior
{
public ReplaceNameBehavior(string operationName)
: base(operationName)
{
AfterReceive = ReplaceName;
}
private static MemoryStream ReplaceName(MemoryStream stream)
{
var message = Encoding.UTF8.GetString(stream.ToArray());
var newMessage = Regex.Replace(message, "<a:Name>.*</a:Name>", "<a:Name>Juan</a:Name>");
return new MemoryStream(Encoding.UTF8.GetBytes(newMessage));
}
}
public class AddZerosToIdsBehavior : TransformBehavior
{
public AddZerosToIdsBehavior(string operationName)
: base(operationName)
{
BeforeSend = AddZeros;
}
private static MemoryStream AddZeros(MemoryStream stream)
{
var message = Encoding.UTF8.GetString(stream.ToArray());
var newMessage = Regex.Replace(message,
@"(<id>)(\d*)(</id>)",
m => m.Groups[1].Value + string.Format("{0:D4}", int.Parse("0" + m.Groups[2].Value)) + m.Groups[3].Value);
return new MemoryStream(Encoding.UTF8.GetBytes(newMessage));
}
}
}
using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Xml;
using TinyClient.CustomerService;
namespace TinyClient
{
public delegate MemoryStream MessageTransformer(MemoryStream stream);
public abstract class TransformBehavior : IEndpointBehavior, IClientMessageInspector
{
private readonly string _operationName;
protected MessageTransformer BeforeSend { get; set; }
protected MessageTransformer AfterReceive { get; set; }
protected TransformBehavior(string operationName)
{
_operationName = operationName;
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(this);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var action = request.Headers.Action;
var actionName = action.Substring(action.LastIndexOf('/') + 1);
if (actionName == _operationName && BeforeSend != null)
{
var oldStream = MessageToStream(request);
var newStream = BeforeSend(oldStream);
request = CloneMessage(request, newStream);
}
return actionName;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
var actionName = correlationState as string;
if(actionName == _operationName && AfterReceive != null)
{
var oldStream = MessageToStream(reply);
var newStream = AfterReceive(oldStream);
reply = CloneMessage(reply, newStream);
}
}
private static MemoryStream MessageToStream(Message message)
{
var ms = new MemoryStream();
using(var xw = XmlWriter.Create(ms))
{
message.WriteMessage(xw);
xw.Flush();
return ms;
}
}
private static Message CloneMessage(Message oldMessage, Stream stream)
{
var xdr = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas());
var message = Message.CreateMessage(xdr, int.MaxValue, oldMessage.Version);
message.Properties.CopyProperties(oldMessage.Properties);
return message;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment