При обновлении SOAP-сервиса, созданного в Delphi 2007, до версии Delphi 10.1 Berlin, разработчики столкнулись с проблемой декодирования URL-encoded символов. Ошибка "No mapping for the Unicode character exists in the target multi-byte code page" возникает при попытке WebBroker HttpApp обработать параметры запроса, содержащие URL-encoded символы в строке запроса, например, http://localhost/soap/soap.dll/action?param=%E0.
Проблема заключается в методе TURLEncoding.DoDecode модуля System.NetEncoding, который пытается преобразовать URL-encoded символы только в кодировку UTF-8, без использования fallback на Windows-1252. Например, строка %E0 в кодировке Windows-1252 представляет символ à, но Delphi пытается декодировать его как UTF-8 версию %C3%A0.
Подтвержденный ответ
Для решения проблемы можно добавить fallback в метод TURLEncoding.DoDecode, который позволит обработать случаи, когда строка не может быть декодирована в UTF-8. Вот пример кода с добавленным fallback:
function TURLEncoding.DoDecode(const Input: string): string;
var
Sp, Cp: PChar;
I: Integer;
Bytes: TBytes;
begin
// ... (код инициализации переменных и начало цикла)
try
Result := TEncoding.UTF8.GetString(Bytes); // Оригинальная строка из Delphi 10.1
except
on E: EEncodingError do
Result := string(PChar(Bytes)); // Fallback, если декодирование в UTF-8 не удалось
end;
// ... (продолжение кода)
end;
Этот код позволяет в случае возникновения исключения EEncodingError при попытке декодирования строки в UTF-8, использовать fallback, который просто возвращает байтовый массив как строку, что может быть интерпретировано в различных кодировках в зависимости от контекста.
Альтернативный ответ
Также было предложено использовать директиву WEB.ReqMulti в проекте WebBroker, что помогло избежать аналогичной ошибки при обработке POST-запросов с мультибайтовыми символами.
Заключение
При работе с SOAP-сервисами в Delphi 10.1 Berlin важно учитывать особенности декодирования URL-encoded символов, особенно при переходе с версий, использующих Windows-1252, на UTF-8. Добавление fallback в метод TURLEncoding.DoDecode может помочь решить проблему с декодированием, а использование WEB.ReqMulti может быть полезным дополнением при работе с мультибайтовыми запросами.
Проблема связана с декодированием URL-encoded символов в SOAP-сервисах Delphi 10.1 Berlin, где возникла ошибка из-за несоответствия кодировок UTF-8 и Windows-1252 при попытке преобразовать URL-encoded символы.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS