Delphi 2010中Indy IdHttp Post存在问题

5
我有一个问题,涉及Indy IdHttp Post方法。使用Delphi 2007编译的Function CallRpc()正常工作,但是使用Delphi 2010编译的相同代码会引发异常。
当我将Delphi 2007的Indy TIdHttp更改为Delphi 2010的Indy TIdHttp时,我需要考虑什么?
function CallRpc(const sURL, sXML: string): string;
var
  SendStream : TStream;
  IdHttp     : TIdHttp;
begin
  SendStream := TMemoryStream.Create;
  IdHttp := TIdHttp.Create(nil);
  try
      IdHttp.Request.Accept        := '*/*';
      IdHttp.Request.ContentType   := 'text/sXML';
      IdHttp.Request.Connection    := 'Keep-Alive';
      IdHttp.Request.ContentLength := Length(sXML);

      StringToStream(sXML, SendStream);  
      SendStream.Position := 0;

      Result := IdHttp.Post(sURL, SendStream);
  finally
    IdHttp.Free;
    SendStream.Free;
  end;
end;

附加内容 2009年1月25日:

异常是:EIdConnClosedGracefully

响应如下:

<?xml version='1.0' encoding='us-ascii'?>
<!DOCTYPE Error [ <!ELEMENT Error (ErrorMessage,DebuggingInfo*)> <!ATTLIST Error Date CDATA #REQUIRED Time CDATA #REQUIRED> <!ELEMENT ErrorMessage (#PCDATA )>  <!ELEMENT DebuggingInfo (#PCDATA )> ] >
<Error Date='01/25/2010' Time='08:57:12'>
<ErrorMessage>
    XML SERVER ERROR: There was a SYSTEM ERROR error in the Incoming XML Response: $ZE=&lt;UNDEFINED&gt;lexan+196^%eXMLLexAnalyzer
</ErrorMessage>

解决方案 2009年1月26日:
function CallRpc(const sURL, sXML: string): string; 
var 
  SendStream : TStream; 
  IdHttp     : TIdHttp; 
  sAnsiXML: Ansistring;   // <-- new
begin 
  sAnsiXML := sXML;  // <-- new: Implicit string cast

  SendStream := TMemoryStream.Create; 
  IdHttp := TIdHttp.Create(nil); 
  try 
     IdHttp.Request.Accept        := '*/*'; 
     IdHttp.Request.ContentType   := 'text/sXML'; 
     IdHttp.Request.Connection    := 'Keep-Alive'; 
     IdHttp.Request.ContentLength := Length(sAnsiXML); // <-- new

     SendStream.Write(sAnsiXML[1], Length(sAnsiXML));  // <-- new
     SendStream.Position := 0; 

     Result := IdHttp.Post(sURL, SendStream); 
  finally 
   IdHttp.Free; 
   SendStream.Free; 
  end; 

结束;


欢迎来到 Stack Overflow。请记得包含显著的细节,例如您遇到了哪个异常,以便读者不必猜测。 - Rob Kennedy
当我能够再次使用我的编程电脑并重复错误时,我将包含更多细节。 - pKarelian
2个回答

4

contentLength是以八进制表示的,而你的字符串长度是以字符为单位的。由于Delphi 2009+中Char的大小为2,所以这是不匹配的!

也许将你的XML转换为UTF8字符串会更好。某些应用程序可能不支持USC2 Unicode格式。

你应该提供结果流的大小作为ContentLength。

更好的方法是:不要提供ContentLength,让Indy来处理它。


1

看看将sXML转换为ansistring是否有所不同。

也许该字符串以UTF-16或其他方式进行流式传输。


2
是的。D2009+ 是unicode编码的,如果我没记错,我也需要复制stringtostream函数,并将其适应为ansistring类型的,因为在 D2009+ 中并没有ansistring stringtostream函数。而且我希望我的文件类型保持不变且兼容。 - Marco van de Voort
1
Karelian,字符串类型的变化是Delphi 2010和Delphi 2007之间的主要区别。如果你错过了这一点,那么你可能会错过很多其他的东西。建议您去阅读发布说明。 - Rob Kennedy
好的。但是这个新的Unicode字符串对IdHttp Post没有任何隐藏影响。我担心还会有其他的惊喜。我的旧代码必须仔细检查与Delphi和Indy发布说明的兼容性。 - pKarelian
我在D2010中发现的另一个惊喜是:RadioGroup的行为很奇怪。似乎我无法在运行时设置其单选按钮属性。 - pKarelian
如果您需要“OLD”字符串,可以使用AnsiString。 - Ritsaert Hornstra
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接