2010-01-23 3 views
5

У меня проблема с методом Indy IdHttp Post. Функция CallRpc(), скомпилированная с Delphi 2007, отлично работает, но тот же код, скомпилированный с Delphi 2010, вызывает исключение.Проблема с Indy IdHttp Post в Delphi 2010

Что я должен учитывать при изменении Delphi 2007 Indy TIdHttp to 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; 

Добавление 25.1.2009:

Исключение заключается в следующем: 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> 

Решение 26.1.2009:

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; 

конец;

+0

Добро пожаловать в Stack Overflow. Не забудьте указать подробные данные, такие как **, которое ** исключение вы получаете, чтобы читатели не угадали. –

+0

Я расскажу больше, когда снова смогу использовать свой компьютер для кодирования и повторю ошибку. – pKarelian

ответ

1

посмотреть, делает ли sXML ansistring значение.

Возможно, строка передается в UTF-16 или около того.

+0

Вы имеете в виду, что строка D2007 отличается от строки D2010? – pKarelian

+2

Да. D2009 + - это unicode, IIRC мне тоже пришлось копировать stringtostream и адаптировать его к ansistring, в D2009 + не было ни одного строкового потокового потока. И я хотел, чтобы мой тип файла оставался тем же и совместимым. –

+0

Спасибо. Я попытаюсь исправить свой код. – pKarelian

4

ContentLength находится в октетах, а длина строки - в Chars. Поскольку sizeof (Char) = 2 в Delphi 2009+, это несоответствие!

Возможно, лучше преобразовать ваш XML в/из строки UTF8. Некоторые приложения не будут поддерживать формат Unicode USC2.

Вы должны указать размер результирующего потока как ContentLength.

Еще не сделано: не поставляйте ContentLength и не позволяйте Indy делать это за вас.

+0

Спасибо. Хорошие подсказки. – pKarelian