c# - WCF REST - 覆盖传入的请求数据

标签 c# .net wcf http rest

是否可以在 WCF 中更改传入 HTTP 请求的数据?

我已经找到了如何更改 HTTP 方法(使用传入消息的 IDispatchOperationSelectorHttpRequestMessageProperty)。

我正在编写能够使用 GET 请求(方法和数据存储在查询字符串中)发出“POST”请求的行为。我可以覆盖 HTTP 方法,但我找不到覆盖数据的解决方案。我需要加载存储在查询字符串中的数据并将它们用作 HTTP 正文。

有什么想法吗?

最佳答案

您需要重新创建传入消息,以便消息正文包含您要传递的信息。正文可能采用 XML 或 JSON 格式(开箱即用支持)。下面的代码显示了如何完成此操作的一个示例。

public class StackOverflow_10391354
{
    [ServiceContract]
    public class Service
    {
        [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
    class MyWebHttpBehavior : WebHttpBehavior
    {
        protected override WebHttpDispatchOperationSelector GetOperationSelector(ServiceEndpoint endpoint)
        {
            return new MyOperationSelector();
        }
        public override void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            base.ApplyDispatchBehavior(endpoint, endpointDispatcher);
        }
    }
    class MyOperationSelector : WebHttpDispatchOperationSelector
    {
        protected override string SelectOperation(ref Message message, out bool uriMatched)
        {
            HttpRequestMessageProperty prop = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
            if (message.Headers.To.LocalPath.EndsWith("/Add") && prop.Method == "GET")
            {
                prop.Method = "POST";
                uriMatched = true;
                message = CreateBodyMessage(message);
                return "Add";
            }
            else
            {
                return base.SelectOperation(ref message, out uriMatched);
            }
        }

        private Message CreateBodyMessage(Message message)
        {
            HttpRequestMessageProperty prop = message.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
            string queryString = prop.QueryString;
            NameValueCollection nvc = HttpUtility.ParseQueryString(queryString);
            StringBuilder sb = new StringBuilder();
            sb.Append('{');
            bool first = true;
            foreach (string key in nvc.Keys)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    sb.Append(',');
                }

                sb.Append('\"');
                sb.Append(key);
                sb.Append("\":\"");
                sb.Append(nvc[key]);
                sb.Append('\"');
            }
            sb.Append('}');
            string json = sb.ToString();
            XmlDictionaryReader jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), XmlDictionaryReaderQuotas.Max);
            Message result = Message.CreateMessage(MessageVersion.None, null, jsonReader);
            result.Properties.Add(HttpRequestMessageProperty.Name, prop);
            result.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
            result.Headers.To = message.Headers.To;
            return result;
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "");
        endpoint.Behaviors.Add(new MyWebHttpBehavior());
        host.Open();
        Console.WriteLine("Host opened");

        WebClient c = new WebClient();
        Console.WriteLine(c.DownloadString(baseAddress + "/Add?x=66&y=88"));

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

关于c# - WCF REST - 覆盖传入的请求数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10391354/

相关文章:

c# - 如何在 C# 中获取字典值集合的计数

c# - 查询找出两个数据表中重复的行?

.net - TIBCO.EMS .NET客户端/WCF channel

asp.net - 调试asp.net服务时出现"The breakpoint will not currently be hit. No symbols have been loaded for this document"

c# - 如何制作连接字符串类?

c# - 为什么TemplateBinding无法绑定(bind)Button.Content?

.net - 实例化时找不到数据库对象实例化

c# - 无法填充组合框

c# - 如何访问不属于接口(interface)定义的方法? (同时仍在为接口(interface)编程)

wcf - 使用 netTcpBinding 在 IIS 7.0 中托管 WCF 服务到底需要做什么?