2013-08-20 29 views
5

Tôi có 4 cổng (WW, EU, AU, US), mỗi một trong số họ có dịch vụ web riêng của mình (thông qua PHP có nghĩa là tôi không có quyền kiểm soát).Lỗi XML khi gọi dịch vụ web

Đối với 4 dịch vụ web đó, tôi có 4 khách hàng (được tạo bởi VS.Net Add Web Reference).

Có một phương pháp được gọi là CommonMethod nó giống nhau trên tất cả các dịch vụ web, trả về một đối tượng thuộc loại CommonClass.

  • Khi tôi gọi là phương pháp (sử dụng lớp proxy EU) Tôi nhận được một InvalidOperationException There is an error in XML document (2, 615)., và InnerException nói "Không thể gán đối tượng kiểu NS.com.AU.CommonClass đến một đối tượng kiểu NS.com. EU.CommonClass. ".
  • Khi tôi gọi phương thức đó (sử dụng lớp proxy Hoa Kỳ), tôi nhận được InvalidOperationException There is an error in XML document (2, 615). và InnerException cho biết "Không thể gán đối tượng kiểu NS.com.AU.CommonClass cho đối tượng kiểu NS.com.US.CommonClass ".
  • Khi tôi gọi phương thức đó (sử dụng lớp proxy AU), Không có ngoại lệ nào được ném.
  • Khi tôi gọi phương thức đó (sử dụng lớp proxy của WW) Tôi nhận được InvalidOperationException There is an error in XML document (2, 615). và InnerException nói "Không thể gán đối tượng kiểu NS.com.AU.CommonClass cho một đối tượng kiểu NS.com.WW.CommonClass ".

Tôi đã tìm kiếm trên web về lỗi như vậy, đó là XML nên rất nhiều nội dung không thích hợp xuất hiện và không thể tìm thấy thứ gì đó hữu ích.

Bây giờ tôi nhận thấy, 4 dịch vụ web đang sử dụng cùng một không gian tên trong tài liệu WSDL của họ (xmlns: tns = "urn: rambo.com: RamboComApi"). Đây có phải là nguồn gốc của sự nhầm lẫn và loại trừ ngoại lệ? Tôi có nên yêu cầu các tác giả của các dịch vụ web chọn không gian tên khác nhau cho mỗi dịch vụ web không?

+0

Có vẻ như mã của bạn đang tạo kiểu đối tượng của NS.com.AU.CommonClass và lớp proxy duy nhất có loại đối sánh là lớp proxy AU. Tất cả những người khác phàn nàn rằng bạn đang cố gắng chỉ định NS.com.AU.CommonClass cho NS.com.EU.CommonClass, NS.com.US.CommonClass hoặc NS.com.WW.CommonClass.Nếu WSDL của chúng giống hệt nhau, bạn có thể sử dụng cùng lớp proxy nhưng chỉ thay đổi URL mục tiêu. – Dijkgraaf

+0

Cảm ơn, bạn có ý nghĩa gì đó như [this] (http://stackoverflow.com/a/16407382/502436)? –

+1

Không, bạn không cần phải thay đổi không gian tên, chỉ cần sử dụng proxy bạn đã tạo cho AU và chỉ cần đặt URL mục tiêu để gọi dịch vụ web thích hợp. – Dijkgraaf

Trả lời

2

Dịch vụ web có thể giống hệt nhau, nhưng chúng không giống nhau. Tức là, nó không giống như mã PHP tương tự được lưu trữ ở tất cả các nơi. mã dịch vụ PHP có thể được duy trì riêng biệt. điều này có nghĩa là bạn phải có bốn khách hàng trong mã của bạn. 4 tài liệu tham khảo dịch vụ. Rằng bạn đang làm rất tốt.

bây giờ, bạn có thể sử dụng một ứng dụng khách để chỉ kết nối với máy chủ của riêng mình. vì vậy hãy sử dụng ứng dụng khách của EU để kết nối với EU. sử dụng ứng dụng khách của Hoa Kỳ để kết nối với Hoa Kỳ. ở đây bởi khách hàng tôi có nghĩa là proxy (điều add-service-ref tạo ra)

Mã người tiêu dùng có thể muốn sử dụng dịch vụ bất kể vị trí của họ. cho rằng tôi khuyên bạn nên sử dụng Adapter Pattern. vì thế nó sẽ là một cái gì đó như thế này:

mã của bạn:

IServiceAdapter adapter = ServiceFactory.createAdapter("EU"); 
adapter.DoStuff(); 
... 


    IServiceAdapter         AdapterFactory 
    ---------------         -------------- 
    void DoStuff1();    IServiceAdapter CreateAdapter(string Target) { 
    int DoStuff2();     switch Target { 
              case "EU" 
               return new EUServiceAdapter(); 
               break; 

              case "US" 
               return new USServiceAdapter(); 
               break; 
             } 
            } 



      EU_ServiceAdpater      
     -----------------------     
    (Implement IServiceAdapter)     

    void DoStuff1() { 
      ServiceReference_EU.ServiceObject1.DoStuff1(); 
    } 

    int DoStuff2() { 
      return ServiceReference_EU.ServiceObject1.DoStuff2(); 
    } 




      US_ServiceAdpater      
     -----------------------     
    (Implement IServiceAdapter)     

    void DoStuff1() { 
      ServiceReference_US.ServiceObject1.DoStuff1(); 
    } 

    int DoStuff2() { 
      return ServiceReference_US.ServiceObject1.DoStuff2(); 
    } 

theo cách này, mã khách hàng của bạn sẽ được bảo vệ từ các điểm cuối thực tế. Là một cách tiếp cận thay thế, bạn có thể cấu hình lại các thiết bị đầu cuối trực tiếp mặc dù trong mã cấu hình của khách hàng dịch vụ teh, nhưng tôi sẽ không khuyên bạn nên. Nó phá vỡ thời điểm khi anh chàng EU quyết định thực hiện một thay đổi nhỏ mà anh chàng Mỹ đã không. tốt nhất, đi cho mô hình bộ chuyển đổi.

+0

tôi muốn thêm vào câu trả lời @inquisitive (mà tôi nghĩ là câu trả lời), bạn có thể làm phiền khách hàng của bạn và xem như dịch vụ tương tự đang được gọi cho tất cả các cuộc gọi và đó là vấn đề. – Liran