Я отправляю большую строку из 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".
Основываясь на том, что вы написали в своем собственном ответе, похоже, что проблема заключается в том, как клиентская сторона кодирует строку, а не в том, как сервер интерпретирует он (хотя сервер должен сотрудничать независимо от того, какую кодировку вы используете). Очевидно, вы ожидаете, что он будет закодирован как 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
.
Получил! Функция URLEncode в Delphi (которая использует сторонний компонент NMURL) кодирует £ как "% A3", когда она фактически должна быть "% C2% A3". Я сделал ручную замену на стороне Delphi, чтобы исправить ее, а затем она не требует никаких манипуляций на стороне С#.
Спасибо за все ваши предложения. Это научит меня доверять старым компонентам!
В справке .Net для System.Text.Encoding.Default:
"Получает кодировку для текущей текущей кодовой страницы ANSI".
Похож, что 0xA3 не находится на этой кодовой странице в виде знака фунта. Переключите его в UTF-8, и он должен правильно декодировать этот конкретный символ, но в целом ли это правильная кодировка (независимо от того, что именно происходит в Delphi), я не могу сказать.
Вы можете переключиться на UTF8, изменив первую строку следующим образом:
MemoryStream mr = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(myString)
Я бы рекомендовал использовать кодировку Base64 на стороне Delphi (добавить блок EncdDecd к вашему предложению и методу EncodeString) и декодировать его на стороне С# с помощью.
public static string DecodeString(string base64EncodedString)
{
byte[] dataToDecode = Convert.FromBase64String(base64EncodedString);
string result = Encoding.ASCII.GetString(dataToDecode);
return result;
}
Удачи.
Насколько я знаю, строка в .NET является UTF-16, поэтому вы можете попробовать использовать соответствующую Widestring в Delphi < 2009. В Delphi 2009 строки по умолчанию UTF-16, но убедитесь, что вы применяете кодировку.