2010-11-11 34 views
10

Tôi đã nhập WSDL và sử dụng nó để gửi yêu cầu SOAP. Có vẻ như sau:Xóa vùng tên khỏi yêu cầu SOAP

<?xml version="1.0"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <SOAP-ENV:Body> 
     <Calculate xmlns="urn:xx.WSDL.xxxxxWebService"> 
      <ContractdocumentIn> 
       <AL> 
       ...More XML... 

Sự cố là phần xmlns="urn:xx.WSDL.xxxxxWebService" trong phần tử Tính toán. Dịch vụ web không thể chấp nhận điều này. Các dịch vụ web không thích không gian tên như thế này ...
Sử dụng SoapUI tôi thấy yêu cầu này chỉ làm việc tốt:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:col="http://example.com.service.xxx/"> 
    <SOAP-ENV:Body> 
     <col:Calculate> 
      <ContractdocumentIn> 
       <AL> 
        ...More XML... 

Vì vậy, làm thế nào để tôi thay đổi theo yêu cầu từ người đầu tiên phiên bản thứ hai? (Nếu không sử dụng thủ đoạn bẩn thỉu!)
(Re-nhập khẩu không phải là một vấn đề nếu điều này sẽ dẫn đến việc định dạng yêu cầu thích hợp.)




Một lần nữa: không có thủ đoạn bẩn cho phép, như hack dòng yêu cầu sửa đổi nó !


Và trong khi tôi đã không hoàn toàn được thử nghiệm nó, có vẻ như C#/VS2010 và Delphi 2010 cũng không thể sử dụng các dịch vụ web mà tôi đang cố gắng để gọi. Một dịch vụ web dường như được viết bằng Java. SoapUI xảy ra để được viết bằng Java, do đó chúng tôi có một khách hàng Java nói chuyện với một dịch vụ Java, mà dường như làm việc tốt. Nhưng bất kỳ khách hàng nào khác?
Dù sao thì, thời gian để thêm hai thẻ nữa: "Java", vì đây là dịch vụ Java và "vs2010" vì .NET cũng không thích dịch vụ này.
Và tôi chuẩn bị viết một trình bao bọc xung quanh dịch vụ này trong .NET, hy vọng nó sẽ hoạt động ... Nó không có. Đây là một lỗ hổng rất nghiêm trọng, có thể là lỗ hổng Java ...

+0

Chúc may mắn. Tôi đã phải dùng đến những thủ thuật bẩn thỉu. –

+0

Vâng, tôi biết. Tôi có lẽ có thể giải quyết nó bằng cách sử dụng thủ đoạn bẩn thỉu, nhưng quản lý không đồng ý với điều đó. Vì vậy, mã cần phải được sạch sẽ. –

+2

Mã SOAP cung cấp các móc để bạn kiểm tra XML đang được gửi và sửa đổi nó nếu bạn cần. Nó hỗ trợ thao tác thủ công một cách rõ ràng. Và mã sẽ ở đó - không có gì "bẩn" về thao tác sau xây dựng. Có thể không được tốt đẹp như tự động, nhưng không ai phải lo lắng về nó. – mj2008

Trả lời

14

Nếu một dịch vụ dự đoán:

<col:Calculate> 
    <ContractdocumentIn> 
     <AL> 

và Delphi SOAP được gửi ...

<Calculate xmlns="urn:xx.WSDL.xxxxxWebService"> 
     <ContractdocumentIn> 
      <AL> 

... vấn đề là ContractdocumentIn là một yếu tố không đủ tiêu chuẩn và (cho đến Delphi XE) Delphi SOAP không hỗ trợ các phần tử không đủ tiêu chuẩn là các phần tử mức cao nhất của một hoạt động. Các phần tử mức cao nhất là các tham số của hàm và không có nơi nào để lưu trữ thực tế rằng phần tử cơ bản phải không đủ tiêu chuẩn; đối với các phần tử ánh xạ tới các thuộc tính, chúng tôi sử dụng Chỉ mục của thuộc tính để lưu trữ cờ IS_UNQL.

BTW, không cần sử dụng tiền tố. Dịch vụ sẽ (cũng phải) cũng chấp nhận:

<Calculate xmlns="urn:xx.WSDL.xxxxxWebService"> 
     <ContractdocumentIn xmlns=""> 
      <AL> 

Cách thứ hai là tiết hơn nhưng tương đương với tiền tố.

Trong ô Delphi XE, nhà nhập khẩu lưu trữ thực tế là một tham số cụ thể ánh xạ tới một phần tử không đủ tiêu chuẩn và thời gian chạy hoạt động trên thông tin này. Tôi đã đăng bản vá lỗi dựa trên việc thực hiện XE cho D2010 và D2007 trong nhóm tin khi nó đã đưa ra trong một thread gần đây:

https://forums.embarcadero.com/thread.jspa?threadID=43057

Nếu ai đó cần truy cập vào họ (họ trong khu vực nhưng có thể đính kèm đã cuộn đi), xin vui lòng gửi email cho tôi và tôi sẽ làm cho họ có sẵn. [Bbabet tại Embarcadero dot com]

Chúc mừng,

Bruneau

+1

Giải thích tuyệt vời! Cảm ơn. Tôi đang sử dụng D2005 với các bản vá lỗi D2007 cho các thư viện SOAP. Bạn có nghĩ rằng bản sửa lỗi của bạn để các bản vá lỗi D2007 sẽ làm việc cho tôi? –

+4

Có, nó nên. Bản vá tôi đã đăng ở đây: https://forums.embarcadero.com/thread.jspa?messageID=290788 – BruneauB

+0

Nếu bạn gặp sự cố, vui lòng, chỉ cho tôi (hoặc gửi email cho tôi) WSDL và tôi sẽ điều tra. Chúc mừng! – BruneauB

8

OMG! Mất rất nhiều cà phê và nhiều giấc ngủ, nhưng tôi đã giải quyết được vấn đề của mình! Nó cũng rất đơn giản ...
Đầu tiên tôi nhập WSDL, như mong đợi. Điều này sẽ tạo ra một số lớp TRemotable. Sau đó, đối với mỗi TRemotable cần một không gian tên khác, tôi ghi đè lên phương thức ObjectToSOAP()! (Và bao gồm XMLIntf vào nguồn WSDL.) Trong trường hợp của tôi với mã như thế này đối với một số loại có thể truy cập từ xa:

function AL2.ObjectToSOAP(RootNode, ParentNode: IXMLNode; const ObjConverter: IObjConverter; const NodeName, NodeNamespace, ChildNamespace: InvString; ObjConvOpts: TObjectConvertOptions; out RefID: InvString): IXMLNode; 
begin 
    Result := inherited ObjectToSOAP(RootNode, ParentNode, ObjConverter, NodeName, '', '', ObjConvOpts, RefID); 
end; 

Làm việc ở Delphi XE. Trong Delphi 2007 tôi đã phải sử dụng các đơn vị XMLIntf và XMLDoc cộng với mã này trên kiểu đầu vào:

function ContractdocumentInType.ObjectToSOAP(RootNode, ParentNode: IXMLNode; const ObjConverter: IObjConverter; const Name, URI: InvString; ObjConvOpts: TObjectConvertOptions; out RefID: InvString): IXMLNode; 

    procedure AlterChildren(Child: IXMLNode); 
    var 
    I: Integer; 
    begin 
    if (Child.NodeType = ntElement) then Child.SetAttributeNS('xmlns', '', ''); 
    for I := 0 to Pred(Child.ChildNodes.Count) do 
     AlterChildren(Child.ChildNodes[I]); 
    end; 

begin 
    Result := inherited ObjectToSOAP(RootNode, ParentNode, ObjConverter, Name, '', ObjConvOpts, RefID); 
    AlterChildren(Result); 
end; 

Đó là một hack, theo ý kiến ​​của tôi. Nhưng nó không phải là một trong rất bẩn. Đó là một chút thử nghiệm, nắm bắt các yêu cầu SOAP và phản hồi để kiểm tra nội dung của họ và để xem nó có sử dụng các không gian tên thích hợp không. Thật không may, Delphi XE làm một công việc tốt hơn lúc này hơn Delphi 2007.

Tuy nhiên, tôi giữ Q này mở cho bất kỳ giải pháp tốt hơn ...


Btw, để thêm col: đến đầu ra, Tôi cũng phải thay đổi dòng này trong WSDL RemClassRegistry.RegisterXSClass(Calculate, 'http://colan.ogconnect.service.wzp/', 'Calculate'); thành: RemClassRegistry.RegisterXSClass(Calculate, 'http://colan.ogconnect.service.wzp/', 'cal:Calculate');. Kết quả sau đó trở thành <cal:Calculate xmlns:cal="http://example.webservice/">. Ont nhiều điều cần phải được thực hiện, mặc dù: di chuyển rằng xmlns:cal đến tiêu đề xml. Nhưng như bây giờ, nó hoạt động cho tôi.


lưu ý khác: cho WSDL tôi đã sử dụng các cài đặt sau: 'Một Outparam là trở lại', 'Thư giãn params đen', 'Tạo destructors', 'bình luận Cảnh báo', 'phát ra loại đen', 'Chuỗi bản đồ để mở rộng'. Các tùy chọn khác là: 'Tạo thông tin chi tiết về các loại và giao diện', 'Bỏ qua các kiểu khung với HTTP Bindings', 'Xác thực các thành viên liệt kê', 'Nhập loại lỗi', 'Nhập loại tiêu đề', 'Quy trình được bao gồm và lược đồ được nhập', 'Tạo lớp bí danh là loại lớp ',' Cho phép tham số Out 'và' Process nillable và các phần tử tùy chọn '. Các loại phát ra các loại chữ là thực tế bởi vì nó tạo ra một lớp xung quanh phương thức duy nhất mà tôi đang gọi. Thật không may, điều này sẽ không giúp được gì nhiều, mặc dù lớp này sẽ giúp bạn sửa đổi yêu cầu SOAP ở cấp cao hơn trong phong bì bằng cách ghi đè phương thức ObjectToSOAP().
Tạo chính phong bì nằm trong đơn vị SOAPEnv và được sử dụng trong đơn vị OPToSOAPDomConv. Thật không may, tôi đã không tìm thấy một phương pháp dễ dàng để truy cập vào phong bì chính nó để thay đổi tiêu đề để thêm không gian tên bổ sung này. Sau đó, một lần nữa, tôi có thể ghi đè lên lớp TSOAPDomConv với phiên bản của riêng tôi mà thêm không gian tên bổ sung. Nhưng mã này đang làm việc cho tôi bây giờ, và như cha tôi đã nói với tôi, khi anh ấy học tôi chương trình: không bao giờ sửa chữa bất cứ thứ gì không bị hỏng.

+0

Có vẻ đầy hứa hẹn - Tôi sẽ cho nó một vòng xoáy. Điều này có thể tiết kiệm rất nhiều thời gian/đau đớn cho một dự án lớn sắp tới, vì vậy tôi rất vui được đóng góp điểm thưởng vào cuộc thảo luận. –

+0

Nó thực sự cung cấp cho bạn đầu ra như thế này:

+0

Tôi nghĩ rằng điều này có thể cho tôi một nơi tốt đẹp để móc vào, nhưng tôi có thể cần phải làm nhiều việc hơn trong chức năng AlterChildren. –

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