繁体   English   中英

无法使IClientMessageFormatter工作

[英]Can't get IClientMessageFormatter to work

我有自定义IClientMessageFormatter,它当前在消息中添加了指定xml元素的属性:

public class GetOrdersMessageFormatter : IClientMessageFormatter
{
    readonly IClientMessageFormatter original;

    public GetOrdersMessageFormatter(IClientMessageFormatter actual)
    {
        original = actual;
    }

    public void AddArrayNamespace(XmlNode node)
    {
        if (node != null)
        {
            var attribute = node.OwnerDocument.CreateAttribute("test");
            attribute.Value = "test";
            node.Attributes.Append(attribute);
        }
    }     

    public object DeserializeReply(Message message, object[] parameters)
    {
        return original.DeserializeReply(message, parameters);
    }

    public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
    {
        Message newMessage = null;

        var message = original.SerializeRequest(messageVersion, parameters);

        if (message.Headers.Action == "urn:Mage_Api_Model_Server_HandlerAction")
        {
            var doc = new XmlDocument();

            using (var reader = message.GetReaderAtBodyContents())
            {
                doc.Load(reader);
            }

            if (doc.DocumentElement != null)
            {
                switch (doc.DocumentElement.LocalName)
                {
                    case "call":
                        AddArrayNamespace(doc.SelectSingleNode("//args"));
                        break;
                }
            }

            using (var ms = new MemoryStream())
            {
                using (var xw = XmlWriter.Create(ms))
                {
                    doc.Save(xw);                      

                    ms.Position = 0;
                    using (var xr = XmlReader.Create(ms))
                    {
                        newMessage = Message.CreateMessage(message.Version, null, xr);
                        newMessage.Headers.CopyHeadersFrom(message);
                        newMessage.Properties.CopyProperties(message.Properties);
                    }
                }
            }
        }

        return newMessage;
    }     
}

它给出了例外

System.ArgumentException:用于消息正文的XmlReader必须位于元素上。 参数名称:阅读器

服务器堆栈跟踪:位于System.ServiceModel的System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter writer)的System.ServiceModel.Channels.BodyWriter.WriteBodyContents(XmlDictionaryWriter writer)的System.ServiceModel.Channels.XmlReaderBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)处系统中System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer)的System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(消息消息,BufferManager bufferManager,Int32 initialOffset,Int32 maxSizeQuota)中的.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer)。 ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(消息消息,System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(消息消息),位于System.ServiceModel.Channels.HttpOutput.Send(TimeSpan超时)在System.ServiceModel.Channels.HttpChannelFa ctory.HttpRequestChannel.HttpChannelRequest.SendRequest(消息,TimeSpan超时)在System.ServiceModel.Channels.RequestChannel.Request(消息,TimeSpan超时)在System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息,TimeSpan超时)在系统.ServiceModel.Channels.ServiceChannel.Call(字符串操作,布尔型单向,ProxyOperationRuntime操作,System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime操作)在System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime operation) .ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

我以为,可能是我需要使用message.CreateBufferedCopy()创建消息副本,然后使用该副本加载XmlDocument,但是那也不起作用。 可能有人知道我在做错什么,或者知道例子,这在做几乎相同的事情(我的意思是在发送消息之前影响消息xml)。

格式化程序中的问题在于,您正在使用读取器(和流)创建一条消息,该消息在消息被消耗之前就被丢弃了。 从流和阅读器的创建中删除“ using”语句后,请求通过-请参见下面的代码。

public class StackOverflow_8669406
{
    public class GetOrdersMessageFormatter : IClientMessageFormatter
    {
        readonly IClientMessageFormatter original;

        public GetOrdersMessageFormatter(IClientMessageFormatter actual)
        {
            original = actual;
        }

        public void AddArrayNamespace(XmlNode node)
        {
            if (node != null)
            {
                var attribute = node.OwnerDocument.CreateAttribute("test");
                attribute.Value = "test";
                node.Attributes.Append(attribute);
            }
        }

        public object DeserializeReply(Message message, object[] parameters)
        {
            return original.DeserializeReply(message, parameters);
        }

        public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
        {
            Message newMessage = null;

            var message = original.SerializeRequest(messageVersion, parameters);

            if (message.Headers.Action == "urn:Mage_Api_Model_Server_HandlerAction")
            {
                var doc = new XmlDocument();

                using (var reader = message.GetReaderAtBodyContents())
                {
                    doc.Load(reader);
                }

                if (doc.DocumentElement != null)
                {
                    switch (doc.DocumentElement.LocalName)
                    {
                        case "call":
                            AddArrayNamespace(doc.SelectSingleNode("//args"));
                            break;
                    }
                }

                var ms = new MemoryStream();

                XmlWriterSettings ws = new XmlWriterSettings
                {
                    CloseOutput = false,
                };

                using (var xw = XmlWriter.Create(ms, ws))
                {
                    doc.Save(xw);
                    xw.Flush();
                }

                Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));

                ms.Position = 0;
                var xr = XmlReader.Create(ms);
                newMessage = Message.CreateMessage(message.Version, null, xr);
                newMessage.Headers.CopyHeadersFrom(message);
                newMessage.Properties.CopyProperties(message.Properties);
            }

            return newMessage;
        }
    }

    [ServiceContract(Namespace = "")]
    public interface ITest
    {
        [OperationContract(Action = "urn:Mage_Api_Model_Server_HandlerAction")]
        int call(string args);
    }
    public class Service : ITest
    {
        public int call(string args)
        {
            return int.Parse(args);
        }
    }
    class MyBehavior : IOperationBehavior
    {
        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
            clientOperation.Formatter = new GetOrdersMessageFormatter(clientOperation.Formatter);
        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
        }

        public void Validate(OperationDescription operationDescription)
        {
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
        host.Open();
        Console.WriteLine("Host opened");

        ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
        foreach (OperationDescription operation in factory.Endpoint.Contract.Operations)
        {
            operation.Behaviors.Add(new MyBehavior());
        }

        ITest proxy = factory.CreateChannel();
        Console.WriteLine(proxy.call("4455"));

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM