Отправка знаков фунта из Delphi в веб-сервис C # - PullRequest
2 голосов
/ 05 августа 2009

Я отправляю большую строку из Delphi 5 в веб-сервис C #, и у меня много проблем со знаками фунта (£). Я URLE кодирую строку со стороны Delphi (которая, кажется, преобразует их в «% A3»). Когда он достигает веб-служб C #, он отображается как « ». Я попытался изменить кодировку строки на стороне C # с помощью StreamReader (показано ниже), но лучшее, что я могу сделать, это перейти на знак вопроса (?).

MemoryStream mr = new MemoryStream(System.Text.Encoding.Default.GetBytes(myString));
StreamReader sr = new StreamReader(mr, System.Text.Encoding.Default);
string s = sr.ReadToEnd();

Как я могу получить правильную интерпретацию знаков £?

Пожалуйста, помогите!

(требуется дополнительная информация)

Подпись веб-службы:

[WebMethod]
public string ReadMyString(string PostedString)

В коде Delphi 5 используются сторонние компоненты / код, которые мы успешно использовали в течение многих лет, но мы впервые пытались напрямую общаться с C #. Схема кода показана ниже:

 tmp_Str := URLEncode(myBigString);
 tmp_Str := WinInetPostData(myURL, tmp_Str);

Между этими двумя строками я подтвердил, что знаки £ были правильно преобразованы в «% A3».

Ответы [ 5 ]

3 голосов
/ 06 августа 2009

Исходя из того, что вы написали в ваш собственный ответ , похоже, проблема в том, как клиентская сторона кодирует строку, а не в том, как сервер интерпретирует ее (хотя сервер должен взаимодействовать) независимо от того, какую кодировку вы используете). Вы, очевидно, ожидаете, что он будет закодирован как UTF-8 (это значение по умолчанию для StreamReader, если вы ничего не указали), но я не удивлюсь, если используемая вами библиотека NetMasters даже не будет знать о UTF-8 или любой другой форме Unicode.

Delphi 5 прекрасно справляется с Юникодом через тип WideString, но в нем отсутствует множество вспомогательных функций поддержки. Если вы хотите сохранить свой код в NetMasters, то минимальным изменением для вас является введение библиотеки с поддержкой Unicode, такой как JclUnicode модуль из бесплатного JCL . Там вы можете найти функцию Utf8Encode, которая получит WideString и вернет AnsiString, который затем подходит для передачи в вашу существующую функцию кодирования URL.

Лучше было бы вообще избавиться от кода NM. Бесплатная Indy библиотека имеет функции для кодирования UTF-8 и URL-кодирования, а также для всех других ваших задач, связанных с Интернетом.

Если вы не используете Unicode на стороне клиента, то нет никаких оснований ожидать, что символ «£» будет когда-либо кодироваться как двухбайтовая последовательность c2 a3. Это UTF-8-кодированная форма U + 00a3, кодовая точка для символа фунта.

Если вы не используете Unicode на клиенте, то вам необходимо выяснить, какую кодовую страницу вы используете . Затем укажите эту кодировку на сервере при создании нового StreamReader.

1 голос
/ 05 августа 2009

Понял! Функция URLEncode в Delphi (которая использует сторонний компонент под названием NMURL) кодирует £ как «% A3», тогда как на самом деле это должно быть «% C2% A3». Я сделал ручную замену на стороне Delphi, чтобы исправить это, а затем он вообще не требует никаких манипуляций на стороне C #.

Спасибо за все ваши предложения. Это научит меня верить в старые компоненты!

0 голосов
/ 05 августа 2009

Насколько мне известно, в .NET строки - это UTF-16, поэтому вы можете попробовать использовать соответствующую строку в Delphi <2009. В Delphi 2009 строки по умолчанию - UTF-16, но убедитесь, что вы используете кодировку. </p>

0 голосов
/ 05 августа 2009

Из справки .Net для System.Text.Encoding.Default:

"Получает кодировку для текущей кодовой страницы ANSI системы."

Похоже, 0xA3 не находится в этой кодовой странице как знак решетки. Переключите его на UTF-8, и он должен правильно декодировать этот конкретный символ, но не могу ли я сказать, является ли это правильной кодировкой в ​​целом (это то, что излучает delphi).

Вы можете переключиться на UTF8, изменив первую строку следующим образом:


MemoryStream mr = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(myString)

0 голосов
/ 05 августа 2009

Я бы порекомендовал использовать кодировку Base64 на стороне Delphi (добавьте модуль EncdDecd к вашему предложению использования и методу EncodeString) и декодировать его на стороне C # с помощью ...

public static string DecodeString(string base64EncodedString)
  {
     byte[] dataToDecode = Convert.FromBase64String(base64EncodedString);
     string result = Encoding.ASCII.GetString(dataToDecode);
     return result;
  }

Удачи.

...