ISO-8859-1 до UTF8 в ASP.NET 2 - PullRequest
3 голосов
/ 18 июня 2009

У нас есть страница, которая отправляет данные в наше приложение ASP.NET в ISO-8859-1

<head>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
    <title>`Sample Search Invoker`</title>
</head>
<body>

<form name="advancedform" method="post" action="SearchResults.aspx">
    <input class="field" name="SearchTextBox" type="text" />
    <input class="button" name="search" type="submit" value="Search &gt;" />
</form>

и в коде позади (SearchResults.aspx.cs)

System.Collections.Specialized.NameValueCollection postedValues = Request.Form;
String nextKey;
for (int i = 0; i < postedValues.AllKeys.Length; i++)
{
    nextKey = postedValues.AllKeys[i];

    if (nextKey.Substring(0, 2) != "__")
    {
        // Get basic search text
        if (nextKey.EndsWith(XAEConstants.CONTROL_SearchTextBox))
        {
            // Get search text value
            String sSentSearchText = postedValues[i];

            System.Text.Encoding iso88591 = System.Text.Encoding.GetEncoding("iso-8859-1");
            System.Text.Encoding utf8 = System.Text.Encoding.UTF8;

            byte[] abInput = iso88591.GetBytes(sSentSearchText);

            sSentSearchText = utf8.GetString(System.Text.Encoding.Convert(iso88591, utf8, abInput));

            this.SearchText = sSentSearchText.Replace('<', ' ').Replace('>',' ');
            this.PreviousSearchText.Value = this.SearchText;
        }
    }
}

Когда мы проходим через Merkblätter, он извлекается из postsValues ​​[i] как Merkbl tter. Необработанная строка: Merkbl% ufffdtter

Есть идеи?

Ответы [ 7 ]

7 голосов
/ 18 июня 2009

У вас есть эта строка кода: -

String sSentSearchText = postedValues[i];

Здесь произошла расшифровка октетов в посте.

Проблема в том, что http-эквивалент META не сообщает серверу о кодировке.

Вы можете просто добавить RequestEncoding = "ISO-8859-1" в директиву @Page и прекратить пытаться возиться с декодированием самостоятельно (поскольку это уже произошло).

Это тоже не поможет. Кажется, вы можете указать только кодировку запроса в файле web.config.

Лучше было бы вообще прекратить использование ISO-8859-1 и оставить для него кодировку UTF-8 по умолчанию. Я не вижу никакой выгоды и только боли при использовании ограничительного кодирования.

Редактировать

Если кажется, что изменение кодировки форм публикации невозможно, то у нас, похоже, не остается другой альтернативы, кроме как самим заниматься декодированием. Для этого включите эти два статических метода в ваш принимающий код: -

private static NameValueCollection GetEncodedForm(System.IO.Stream stream, Encoding encoding)
{
    System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.ASCII);
    return GetEncodedForm(reader.ReadToEnd(), encoding);
}


private static NameValueCollection GetEncodedForm(string urlEncoded, Encoding encoding)
{
    NameValueCollection form = new NameValueCollection();
    string[] pairs = urlEncoded.Split("&".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

    foreach (string pair in pairs)
    {
        string[] pairItems = pair.Split("=".ToCharArray(), 2, StringSplitOptions.RemoveEmptyEntries);
        string name = HttpUtility.UrlDecode(pairItems[0], encoding);
        string value = (pairItems.Length > 1) ? HttpUtility.UrlDecode(pairItems[1], encoding) : null;
        form.Add(name, value);
    }
    return form;
}

Теперь вместо назначения: -

postedValues = Request.Form;

использование: -

postValues = GetEncodedForm(Request.InputStream, Encoding.GetEncoding("ISO-8859-1"));

Теперь вы можете удалить кодировку marlarky из остальной части кода.

2 голосов
/ 23 марта 2010

У нас была та же проблема, что и у вас. Тема совсем не простая.

Первый совет - установить кодировку Response для страницы, на которой данные (обычно это та же страница, которая получает данные в .NET), на желаемую форму после кодирования.

Однако это всего лишь подсказка браузеру пользователя о том, как интерпретировать символы, отправленные с сервера. Пользователь может переопределить кодировку вручную. И, если пользователь переопределяет кодировку страницы, кодировка данных, отправляемых в форме, также изменяется (на то, что пользователь установил в кодировке).

Хотя есть маленькая хитрость. Если вы добавите в форму скрытое поле с именем _charset_ (обратите внимание на подчеркивание), большинство браузеров заполнят это поле формы именем кодировки, использованной при публикации формы. Это поле формы также является частью спецификации HTML5.

Таким образом, вы можете подумать, что все в порядке, однако, когда на вашей странице ASP.NET уже URL-кодировал все параметры, отправленные в форму. Поэтому, когда у вас действительно есть значение в поле _charset_, значение поля, содержащего Merkblätter , уже неправильно декодируется .NET.

У вас есть два варианта:

  1. На рассматриваемой странице ASP.NET выполните синтаксический анализ строки запроса вручную
  2. В Application_BeginRequest, в Global.asax, проанализируйте параметры запроса вручную, извлекая поле _charset_. Когда вы получите значение, установите Request.ContentEncoding на System.Text.Encoding.GetEncoding(<value of _charset_ field>). Если вы сделаете это, вы можете читать значение поля, содержащего Merkblätter , как обычно, независимо от того, в какую кодировку клиент отправляет значение.

В любом из вышеперечисленных случаев вам нужно вручную прочитать Request.InputStream, чтобы получить данные формы. Я бы порекомендовал установить для Response Encoding значение UTF-8, чтобы иметь наибольшее количество опций, в которых вы принимаете символы, а затем обрабатывать особые случаи, когда пользователь особенно переопределил кодировку, как указано выше.

2 голосов
/ 18 июня 2009

Я думаю, что добавление вашей кодировки в web.config, вероятно, решит вашу проблему:

<configuration>
   <system.web>
      <globalization
           fileEncoding="iso-8859-1"
           requestEncoding="iso-8859-1"
           responseEncoding="iso-8859-1"
           culture="en-US"
           uiCulture="en-US"
        />
   </system.web>
</configuration>
1 голос
/ 24 ноября 2009
Function urlDecode(input)
 inp = Replace(input,"/","%2F")
 set conn = Server.CreateObject("MSXML2.ServerXMLHTTP")
 conn.setOption(2) = SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS
 conn.open "GET", "http://www.neoturk.net/urldecode.asp?url=" & inp, False
 conn.send ""
 urlDecode = conn.ResponseText
End Function

Чтобы ускорить это, просто создайте таблицу в вашей базе данных для декодированных и закодированных URL-адресов и прочитайте их в разделе global.asa application.on_start. Позже поместите их на объект приложения. Затем установите процедуру проверки для этого приложения obj. В приведенной выше функции и если IF-декодированный URL-адрес не существует в массиве приложений, ТОГДА запросите его один раз с удаленной страницы (совет: urldecode.asp должен находиться на другом сервере, см. http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316451) и вставьте его в свою базу данных и добавьте в приложение. массив объекта, ELSE возвращает функцию из приложения obj.

Это лучший метод, который я когда-либо нашел. Если кому-то нужна дополнительная информация об объекте приложения, операциях с базой данных и т. Д., Свяжитесь со мной по адресу admin@neoturk.net

.

Вы можете увидеть вышеописанный метод, успешно работающий по адресу: lastiktestleri.com/Home

Я также использовал версию ISAPI_Rewrite Lite от HeliconTech. использование простое: url = Request.ServerVariables ("HTTP_X_REWRITE_URL") это вернет точный URL, направленный на /404.asp

0 голосов
/ 27 июня 2009

У меня была такая же проблема, решенная так:

  System.Text.Encoding iso_8859_2 = System.Text.Encoding.GetEncoding("ISO-8859-2");
  System.Text.Encoding utf_8 = System.Text.Encoding.UTF8;

  NameValueCollection n = HttpUtility.ParseQueryString("RT=A+v%E1s%E1rl%F3+nem+enged%E9lyezte+a+tranzakci%F3t", iso_8859_2);
  Response.Write(n["RT"]);

A + v% E1s% E1rl% F3 + nem + enged% E9lyezte + a + tranzakci% F3t вернет "Vásárló nem engedélyezte a tranzakciót", как ожидалось.

0 голосов
/ 24 июня 2009

В итоге я заставил наше приложение соответствовать стандарту ISO-8859-1. К сожалению, лежащие в основе данные могут содержать символы, которые плохо вписываются в эту кодовую страницу, поэтому мы просматриваем данные перед их отображением и преобразуем все, что касается кода символа 127, в сущность. Не идеально, но у нас работает ...

0 голосов
/ 18 июня 2009

Это потому, что вы кодируете строку как ISO-8859-1 и декодируете ее, как если бы она была строкой, закодированной как UTF-8. Это, несомненно, испортит данные.

Форма не публикует данные как ISO-8859-1 только потому, что вы отправляете страницу с использованием этой кодировки. Вы не указали никакой кодировки для данных формы, поэтому браузер выберет кодировку, способную обрабатывать данные в форме. Он может выбрать ISO-8859-1, но может также выбрать и другую кодировку.

Данные отправляются на сервер, где они декодируются и помещаются в коллекцию Request.Form в соответствии с кодировкой, указанной браузером.

Все, что вам нужно сделать, это прочитать строку, которая уже была декодирована из коллекции Request.Form. Вам также не нужно перебирать все элементы в коллекции, поскольку вы уже знаете название текстового поля.

Просто сделай:

string sentSearchText = Request.Form("SearchTextBox");
...