2012-04-30 9 views
1

是否可以在WCF中更改傳入HTTP請求的數據?WCF REST - 覆蓋傳入的請求數據

我已經發現如何更改HTTP方法(使用傳入消息的IDispatchOperationSelectorHttpRequestMessageProperty)。

我寫的行爲可以使用GET請求(存儲在查詢字符串中的方法和數據)發出「POST」請求。我可以重寫HTTP方法,但我找不到覆蓋數據的解決方案。我需要加載存儲在查詢字符串中的數據並將它們用作HTTP主體。

有什麼想法?

+0

你有沒有看看消息檢查員:http://msdn.microsoft.com/en-us/library/aa717047.aspx – Rajesh

回答

2

你需要讓郵件正文包含要傳遞的信息來重新創建傳入消息。正文可能是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(); 
    } 
} 
+0

我以前在URL中的數據不同的編碼,但我設法得到它工作。我甚至沒有想到消息的重現是可能的。謝謝,我感謝你的幫助。 –