代码之家  ›  专栏  ›  技术社区  ›  LukLed

如何在delphi7中更改TXSDateTime SOAP序列化?

  •  0
  • LukLed  · 技术社区  · 15 年前

    我正在尝试使用基于Java的Web服务并请求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" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
      <SOAP-ENV:Body xmlns:NS1="http://something/">
        <NS1:getRequest id="1">
          <sessionId xsi:type="xsd:string"></sessionId>
          <reportType xsi:type="NS1:reportType">ALL</reportType>
          <xsd:dateFrom xsi:type="xsd:dateTime">2010-05-30T23:29:43.088+02:00</xsd:dateFrom>
          <xsd:dateTo xsi:type="xsd:dateTime">2010-05-31T23:29:43.728+02:00</xsd:dateTo>
        </NS1:getRequest>
        <parameters href="#1" />
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

          <xsd:dateFrom xsi:type="xsd:dateTime">2010-05-30T23:29:43.088+02:00</xsd:dateFrom>
          <xsd:dateTo xsi:type="xsd:dateTime">2010-05-31T23:29:43.728+02:00</xsd:dateTo>
    

          <dateFrom xsi:type="xsd:dateTime">2010-05-30T23:29:43.088+02:00</xsd:dateFrom>
          <dateTo xsi:type="xsd:dateTime">2010-05-31T23:29:43.728+02:00</xsd:dateTo>
    

    一切正常,但是Delphi(没有Delphi源代码更改)不允许更改生成的XML,它只有一些选项。可以设置转换选项吗 TSXDateTime <dateFrom ,不是 <xsd:dateFrom 标签?你遇到那个问题了吗?

    2 回复  |  直到 15 年前
        1
  •  0
  •   Chris Thornton    15 年前

    您可以在反序列化之前拦截XML,并使用stringreplace编辑核心内容。你需要参加里约的一个活动。

    更新:点击这里: HTTPRIO1AfterExecute(const MethodName:string;soap响应:TStream);

    Edit:OnAfterExecute存在于D2007和更高版本中,您可以通过使用D2007 SOAP源在D2005中使用它。不太清楚D7!你可能是索尔。

    编辑:在D7上,您可能会修改代码以提供自己的OnAfterExecute事件。i、 e.修改rio.pas以包含处理程序。此外,处理流对象时的一个常见错误是,在完成操作时未能将位置重置为0。

    Edit:您也可以在BeforeExecute中编辑请求,尽管可能不使用Delphi7代码。在D2010中(我现在已经看到了),SOAPRequest是一个流。在D2007中(我已经做了大量的工作,但实际上在D2005上使用了D2007代码),我相信它是一个字符串。在我的D2005/2007项目中,我们使用onbeforecute中的一系列StringReplace()语句广泛地编辑请求。

        2
  •  0
  •   LukLed    15 年前

    DoBeforeExecute virtual OnBeforeExecute ). 然后我将从WSDL单元自动生成的更改为使用tmyhtprio:

    unit MyHttpRIO;
    
    interface
    
    uses
      RIO, Classes, SOAPHTTPClient;
    
    type
      TMyHttpRIO = class(THttpRIO)
        procedure DoBeforeExecute(const MethodName: string; Request: TStream); override;
      private
      end;
    
    implementation
    
    { TMyHttpRIO }
    
    procedure TMyHttpRIO.DoBeforeExecute(const MethodName: string;
      Request: TStream);
    var
      StrStrm: TStringStream;
      SavedRequest: WideString;
      ReqWideStr: WideString;
    begin
      if Assigned(OnBeforeExecute) then
      begin
        { Ideally we would change the signature of this event to take a Stream.
          The change to stream was necessary for attachment and encoding support.
          And it makes the event consistent.... However, for the sake of
          backward compatibility.... }
        StrStrm := TStringStream.Create('');
        try
          StrStrm.CopyFrom(Request, 0);
          Request.Position := 0;
          ReqWideStr := UTF8Decode(StrStrm.DataString);
          SavedRequest := ReqWideStr;
          OnBeforeExecute(MethodName, ReqWideStr);
        finally
          StrStrm.Free;
        end;
        if (Length(SavedRequest) <> Length(ReqWideStr)) or (SavedRequest <> ReqWideStr) then
        begin
          // Copy changes made to ReqWideStr in the event back to the Request stream
          StrStrm := TStringStream.Create(string(ReqWideStr));
          try
            StrStrm.Position := 0;
            Request.Size := 0;
            Request.CopyFrom(StrStrm, 0);
            Request.Position := 0;
          finally
            StrStrm.Free;
          end;
        end;
      end;
    end;
    
    end.