2011-06-22 47 views
10

Tôi có một cuộc gọi AJAX mà tôi muốn chạy đối với dịch vụ WCF GET. Về cơ bản, cuộc gọi đến dịch vụ (thông qua jquery) trông như thế này:Chuyển một mảng tới dịch vụ WCF qua GET

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

Khi cuộc gọi này được chạy, tôi thấy GET trong firebug đi qua một cách chính xác, và tôi làm đạt điểm cuối. Tuy nhiên, tham số statusTypes luôn là giá trị rỗng.

Các GET chính nó từ jquery vẻ như nó được mã hóa, nhưng khi tôi không mã hóa các dấu ngoặc, cuộc gọi sẽ không được vào thiết bị đầu cuối tại tất cả:

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

Và các dịch vụ WCF bản thân:

[OperationContract]

[WebInvoke (Method = "GET", bodystyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json)]

công ResultsViewModel GetTags (chuỗi truy vấn, int [] statusTypes)

Có thể thế nào để vượt qua một mảng thông qua GET đến một dịch vụ WCF?

Các hoán vị không nhiều, vì vậy tôi có thể viết một điểm cuối cá nhân "cho mỗi mảng", nhưng tôi muốn giữ nó trong một.

+1

Là một workaround, bạn chuyển đổi mảng của bạn thành một chuỗi và sau đó phân tích nó trong dịch vụ của bạn sử dụng String.split (). – Zachary

Trả lời

9

Có thể, nhưng không phải với WCF ngoài hộp. Với "hỗ trợ jQuery" trong WCF codeplex page, bạn có thể nhận tất cả dữ liệu được gửi bởi jQuery (bao gồm mảng, đối tượng lồng nhau, v.v.) trong biến không định dạng, cả trên cơ thể (đối với yêu cầu POST) và chuỗi truy vấn (cho ĐƯỢC). Việc ánh xạ giữa các biến mảng jQuery (có tên chứa '[' và ']') và các tham số hoạt động không thể được thực hiện trong WCF 4.0 (ít nhất là không phải viết một trình định dạng thông báo).

Điều này sẽ đơn giản hơn, trên các API web WCF mới (cũng có sẵn trên trang web codeplex).

Cập nhật: đây là một ví dụ về một định dạng mà làm việc cho kịch bản của bạn:

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

Bạn sẽ đăng ký lớp hành vi tùy chỉnh thông qua app.config thay vì mã như thế nào? –

+1

Tìm thấy câu trả lời cho bản thân mình - cần trả lại từ phần mở rộng hành vi tùy chỉnh: http://www.codeproject.com/Articles/37156/Focus-on-the-Extension-of-WCF-Behavior và thêm nó vào phần mở rộng hành vi trong web.config –

2

Không thể thực hiện được. Bạn không thể ánh xạ mảng giá trị từ URL đến tham số. Nếu bạn muốn vượt qua mảng sử dụng HTTP POST.

+0

Bạn thực sự có thể (xem câu trả lời khác), nó chỉ là không dễ dàng để làm. – carlosfigueira

+0

@carlos: Có, tôi hiểu. Câu trả lời rất hay và rất nhiều công việc để làm cho nó hoạt động. Câu trả lời của tôi được nhắm mục tiêu nhiều hơn đến những gì hiện tại UriTemplate hỗ trợ ra khỏi hộp. Tôi không nghĩ về việc gia hạn. Bạn cũng có thể nắm bắt yêu cầu thô dưới dạng luồng và cố gắng trích xuất chuỗi truy vấn. –

Các vấn đề liên quan