GET

2011-06-22 20 views
10

के माध्यम से डब्ल्यूसीएफ सेवा के लिए एक सरणी पास करना मेरे पास एक एजेक्स कॉल है जिसे मैं डब्ल्यूसीएफ जीईटी सेवा के खिलाफ चलाने के लिए चाहता हूं। मूल रूप से, सेवा के लिए कॉल (jQuery के माध्यम से) इस तरह दिखता है:GET

$.get(serviceEndpoint, {query : "some search text", statusTypes: [1, 2]}, function (result) { /* do something*/ }, 'text'); 

जब यह कॉल चलाने हो जाता है, मैं देख रहा हूँ फ़ायरबग में मिलता है सही ढंग से के माध्यम से जाना है, और मैं अंत बिंदु मारा है। हालांकि, पैरामीटर statusTypes हमेशा शून्य है।

jQuery से प्राप्त कर ही लगता है कि यह इनकोडिंग, लेकिन जब मैं कोष्ठक सांकेतिक शब्दों में बदलना नहीं है, कॉल बिल्कुल endpoint प्रवेश नहीं करेंगे:

http://localhost/Services/SomeService.svc/Endpoint?statusTypes%5B%5D=1&statusTypes%5B%5D=2&query=some+search+text

और WCF सेवा ही:

[OperationContract]

[WebInvoke (विधि = "GET", Bodystyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json)]

सार्वजनिक ResultsViewModel GetTags (स्ट्रिंग क्वेरी इंट [] statusTypes)

क्या यह संभव है एक डब्ल्यूसीएफ सेवा के लिए जीईटी के माध्यम से एक सरणी पास करने के लिए?

परमिट कई नहीं हैं, इसलिए मैं एक व्यक्तिगत अंतराल "प्रति सरणी" लिख सकता हूं, लेकिन मैं इसे एक में रखना चाहता हूं।

+1

समाधान के लिए, यदि आप एक स्ट्रिंग के लिए अपने सरणी परिवर्तित और फिर String.Split का उपयोग कर अपने सेवा में उसे पार्स ()। – Zachary

उत्तर

9

यह संभव है, लेकिन आउट ऑफ़ द बॉक्स डब्ल्यूसीएफ के साथ नहीं। WCF codeplex page में "jQuery समर्थन" के साथ, आप शरीर पर (POST अनुरोधों के लिए) और क्वेरी स्ट्रिंग (दोनों के लिए jQuery) (सरणी, नेस्टेड ऑब्जेक्ट्स इत्यादि सहित) द्वारा भेजे गए सभी डेटा को एक untyped चर में प्राप्त कर सकते हैं प्राप्त)। JQuery सरणी चर के बीच मैपिंग (जिनके नाम '[' और ']' होते हैं) और ऑपरेशन पैरामीटर डब्ल्यूसीएफ 4.0 में नहीं किए जा सकते हैं (कम से कम एक संदेश फ़ॉर्मेटर लिखने के बिना नहीं)।

हालांकि, यह डब्ल्यूसीएफ वेब एपीआई (कोडप्लेक्स साइट पर भी उपलब्ध) पर सरल होना चाहिए।

अद्यतन: यह एक फ़ॉर्मेटर जो अपने परिदृश्य के लिए काम करता है की एक उदाहरण है:

public class StackOverflow_6445171 
{ 
    [ServiceContract] 
    public class Service 
    { 
     [WebGet(ResponseFormat = WebMessageFormat.Json)] 
     public string GetLabelPacketTags(string query, int[] statusTypes) 
     { 
      StringBuilder sb = new StringBuilder(); 
      sb.Append("Query=" + query); 
      sb.Append(", statusTypes="); 
      if (statusTypes == null) 
      { 
       sb.Append("null"); 
      } 
      else 
      { 
       sb.Append("["); 
       for (int i = 0; i < statusTypes.Length; i++) 
       { 
        if (i > 0) sb.Append(","); 
        sb.Append(statusTypes[i]); 
       } 
       sb.Append("]"); 
      } 

      return sb.ToString(); 
     } 
    } 
    class MyWebHttpBehavior : WebHttpBehavior 
    { 
     protected override IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint) 
     { 
      return new MyArrayAwareFormatter(operationDescription, this.GetQueryStringConverter(operationDescription)); 
     } 

     class MyArrayAwareFormatter : IDispatchMessageFormatter 
     { 
      OperationDescription operation; 
      QueryStringConverter queryStringConverter; 
      public MyArrayAwareFormatter(OperationDescription operation, QueryStringConverter queryStringConverter) 
      { 
       this.operation = operation; 
       this.queryStringConverter = queryStringConverter; 
      } 

      public void DeserializeRequest(Message message, object[] parameters) 
      { 
       if (message.Properties.ContainsKey("UriMatched") && (bool)message.Properties["UriMatched"]) 
       { 
        UriTemplateMatch match = message.Properties["UriTemplateMatchResults"] as UriTemplateMatch; 
        NameValueCollection queryValues = match.QueryParameters; 
        foreach (MessagePartDescription parameterDescr in this.operation.Messages[0].Body.Parts) 
        { 
         string parameterName = parameterDescr.Name; 
         int index = parameterDescr.Index; 
         if (parameterDescr.Type.IsArray) 
         { 
          Type elementType = parameterDescr.Type.GetElementType(); 
          string[] values = queryValues.GetValues(parameterName + "[]"); 
          Array array = Array.CreateInstance(elementType, values.Length); 
          for (int i = 0; i < values.Length; i++) 
          { 
           array.SetValue(this.queryStringConverter.ConvertStringToValue(values[i], elementType), i); 
          } 
          parameters[index] = array; 
         } 
         else 
         { 
          parameters[index] = this.queryStringConverter.ConvertStringToValue(queryValues.GetValues(parameterName)[0], parameterDescr.Type); 
         } 
        } 
       } 
      } 

      public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) 
      { 
       throw new NotSupportedException("This is a request-only formatter"); 
      } 
     } 
    } 
    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "").Behaviors.Add(new MyWebHttpBehavior()); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     WebClient c = new WebClient(); 
     Console.WriteLine(c.DownloadString(baseAddress + "/GetLabelPacketTags?query=some+text&statusTypes[]=1&statusTypes[]=2")); 
     Console.WriteLine(c.DownloadString(baseAddress + "/GetLabelPacketTags?query=some+text&statusTypes%5B%5D=1&statusTypes%5B%5D=2")); 

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

कोड के बजाए app.config के माध्यम से आप कस्टम व्यवहार वर्ग को कैसे पंजीकृत करेंगे? –

+1

मुझे जवाब मिला - इसे कस्टम व्यवहार एक्सटेंशन से वापस करने की आवश्यकता है: http://www.codeproject.com/Articles/37156/Focus-on-the- एक्सटेंशन-of-WCF- व्यवहार और व्यवहार एक्सटेंशन में जोड़ें web.config में –

2

नहीं, यह संभव नहीं है। आप URL से पैरामीटर के मानों की सरणी मैप नहीं कर सकते हैं। यदि आप सरणी HTTP HTTP का उपयोग करना चाहते हैं।

+0

आप वास्तव में (अन्य उत्तर देखें) कर सकते हैं, यह करना आसान नहीं है। – carlosfigueira

+0

@carlos: हाँ मैं देखता हूं। बहुत अच्छा जवाब और इसे काम करने के लिए बहुत सारे काम। मेरा जवाब बॉक्स के बाहर मौजूदा UriTemplate समर्थन के लिए अधिक लक्षित था। मैंने विस्तार के बारे में नहीं सोचा था। आप स्ट्रीम के रूप में कच्चे अनुरोध को भी कैप्चर कर सकते हैं और क्वेरी स्ट्रिंग निकालने का प्रयास कर सकते हैं। –