Created
December 14, 2013 03:43
-
-
Save lontivero/7955440 to your computer and use it in GitHub Desktop.
Shows how to manipulate raw wcf messages per operation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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