将自定义WCF消息发送到服务

时间:2012-01-10 19:12:58

标签: c# wcf c#-4.0

我的目标是将wcf调用记录到一个IIS托管的wcf服务,并将它们重播到另一个wcf服务。到目前为止,我有一个IDispatchMessageInspector正在this example之后工作,它可以记录传入的请求和相应的回复到磁盘。

如何从磁盘读取消息然后将其发送到其他服务?客户端是否有办法在不通过普通客户端代理对象的情况下向服务发送低级Message对象?

2 个答案:

答案 0 :(得分:1)

是的,如果您在通信协议级别工作,发送原始消息应该很容易。这是我原来的examples之一。

答案 1 :(得分:1)

我只需创建一个IRequestChannel即可让它工作,阅读以下内容有助于解释它是如何工作的

发送邮件的代码:

private static void TestDispatchingMessage()
{
    var reader = XmlDictionaryReader.CreateBinaryReader(new FileStream(@"path\request_6c6fc02f-45a7-4049-9bab-d6f2fff5cb2d.xml", FileMode.Open), XmlDictionaryReaderQuotas.Max);
    var message = Message.CreateMessage(reader, int.MaxValue, MessageVersion.Soap11);
    message.Headers.To = new System.Uri(@"url");


    BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None)
    {
        MessageEncoding = WSMessageEncoding.Mtom,
        MaxReceivedMessageSize = int.MaxValue,
        SendTimeout = new TimeSpan(1, 0, 0),
        ReaderQuotas = { MaxStringContentLength = int.MaxValue, MaxArrayLength = int.MaxValue, MaxDepth = int.MaxValue }
    };

    var cf = new ChannelFactory<IRequestChannel>(binding, new EndpointAddress(@"url"));

    foreach (OperationDescription op in cf.Endpoint.Contract.Operations)
    {
        op.Behaviors.Remove<DataContractSerializerOperationBehavior>();
        op.Behaviors.Add(new ProtoBehaviorAttribute());
    }

    cf.Open();
    var channel = cf.CreateChannel();
    channel.Open();

    var result = channel.Request(message);

    Console.WriteLine(result);

    channel.Close();
    cf.Close();
}

这就是IDispatchMessageInspector类中的内容:

public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
    var callId = Guid.NewGuid();

    var action = request.Headers.Action.Substring(request.Headers.Action.LastIndexOf('/'));
    var fileName = string.Format(@"path\{0}_{1}.data", action, callId);

    try
    {
        var buffer = request.CreateBufferedCopy(int.MaxValue);

        var writeRequest = buffer.CreateMessage();
        using (var stream = new FileStream(fileName, FileMode.CreateNew))
        {
            using (var writer = XmlDictionaryWriter.CreateBinaryWriter(stream))
            {
                writeRequest.WriteMessage(writer);
                writer.Flush();
            }
        }

        request = buffer.CreateMessage();
        buffer.Close();
    }
    catch (Exception ex)
    {
        Log.ErrorException("Error writing", ex);
    }

    Log.Info("Call {0}", callId);

    return callId;
}