2011-06-22 20 views
10

Bir WCF GET hizmetine karşı çalıştırmak istediğim bir AJAX çağrısı var. Temelde, (jquery aracılığıyla) hizmetine çağrı şuna benzer: Bu çağrı koþulur zamanWCF hizmetine bir dizi iletme

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

, ben kundakçı GET doğru geçmesi görüyorum ve son nokta isabet yok. Ancak, statusTypes parametresi her zaman boş.

jquery gelen GET kendisi kodlanmış gibi görünüyor, ama ben parantez kodlamak olmadığında, çağrı hiç bitiş noktası girmeyecektir:

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

Ve WCF hizmeti kendisi:

[OperationContract]

[WebInvoke (Yöntem =
]

, []

mümkün statusTypes)

kamu ResultsViewModel GetTags (string sorgu ResponseFormat = WebMessageFormat.Json) mı int , Bodystyle = WebMessageBodyStyle.WrappedRequest, "GET" bir WCF hizmetine GET aracılığıyla bir dizi geçirmek için?

Permütasyonlar sayısız değildir, bu yüzden "her dizi için" ayrı bir uç nokta yazabilirim, ancak bunu birde tutmayı tercih ederim.

+1

: Bu senaryo için çalışan bir biçimlendiriciden örneğidir). – Zachary

cevap

9

Kutudan çıktığında değil, WCF ile mümkündür. WCF codeplex page'daki "jQuery desteği" ile, her ikisi de gövdedeki (POST istekleri için) ve sorgu dizesinde jQuery (diziler, iç içe nesneler, vb.) Ile birlikte gönderilen tüm verileri bir türlenmemiş değişkende alabilirsiniz. ALMAK). JQuery dizi değişkenleri (isimleri '[' ve ']') ve çalışma parametreleri arasındaki eşleştirme, WCF 4.0'da (en azından bir mesaj biçimlendiricisi yazmadan) yapılamaz. Bununla birlikte, bu yeni WCF Web API'lerinde (ayrıca codeplex sitesinde de bulunabilir) daha basit olmalıdır.

Güncelleme:, bir dizeye dizinizi dönüştürmek ve daha sonra (String.split kullanarak hizmetiniz bunu ayrıştırmak Çözüm olarak

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

Özel davranış sınıfını kod yerine app.config aracılığıyla nasıl kaydedersiniz? –

+1

Yanıtı kendim buldum - özel davranış uzantısından geri göndermeniz gerekiyor: http://www.codeproject.com/Articles/37156/Focus-on-the-Extension-of-WCF-Behavior ve bunu davranış uzantılarına ekleyin web.config içinde –

2

Hayır, bu mümkün değil. Değer dizisini URL'den parametreye eşleyemezsiniz. Dizi geçmek istiyorsanız HTTP POST kullanın.

+0

Aslında (diğer cevaplara bakın) yapabilirsiniz, sadece yapmak kolay değil. – carlosfigueira

+0

@carlos: Evet görüyorum. Çalışması için çok güzel bir cevap ve çok çalışma. Cevabım, mevcut UriTemplate’in kutudan ne desteklediğine daha fazla hedef oldu. Uzatma hakkında düşünmedim. Ayrıca ham isteği bir akış olarak yakalayabilir ve sorgu dizgisini ayıklamaya çalışabilirsiniz. –

İlgili konular