Отправка знаков фунта из Delphi в веб-сервис C #

2

Я отправляю большую строку из Delphi 5 на веб-службу С#, и у меня много проблем с знаками Pound (£). я URLEncode строка со стороны Delphi (которая, кажется, преобразует их в "% A3" ). Когда он достигает веб-служб С#, он отображается как "". Я попытался изменить кодировку строки на стороне С# с помощью 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 используются сторонние компоненты/код, которые мы успешно использовали в течение многих лет, но это первый раз, когда мы попробовали напрямую поговорить с С#. Схема кода приведена ниже:

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

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

  • 1
    Пожалуйста, предоставьте немного подробностей. Как вы отправляете это? Какова подпись операции веб-службы? ASMX или WCF? И, пожалуйста, покажите актуальный код.
  • 0
    Дальнейшие подробности добавлены по запросу - боюсь, это не так уж и много.
Показать ещё 2 комментария
Теги:
web-services
encoding
asmx

5 ответов

3
Лучший ответ

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

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

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

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

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

1

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

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

  • 4
    Сделайте себе гигантскую услугу и угробите код NetMasters со всей поспешностью! Он был глючным, когда был выпущен с Delphi, и теперь он все еще глючит, но также не поддерживается. Как можно скорее переключитесь на хорошую библиотеку, такую как Indy или ICS.
0

В справке .Net для System.Text.Encoding.Default:

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

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

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


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

  • 0
    Спасибо, но я все еще получаю маленькие квадраты с твоим предложением.
  • 0
    Скраб это. Знак фунта будет в двух байтах в UTF8. Попробуйте указать кодовую страницу Великобритании, используя перегрузку GetEncoding (int). Например, GetEncoding (1252) для кодовой страницы Великобритании. Смотрите ( lingoes.net/en/translator/codepage.htm ) список кодовых страниц.
0

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

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

Удачи.

  • 0
    Спасибо за ваше предложение. Я попробовал это и все еще получаю знаки вопроса, я боюсь. Я убежден, что проблема на стороне C # ...
0

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

  • 0
    Извините, я должен был упомянуть, что это Delphi 5 (древний!) - но я попробовал ваше предложение, и мне не повезло, я боюсь. Спасибо, в любом случае

Ещё вопросы

Сообщество Overcoder
Наверх
Меню