Практическое руководство. Преобразование числовых данных, введенных пользователем в веб-элементах управления, в числаHow to: Convert Numeric User Input in Web Controls to Numbers

Веб-страницы могут отображаться в любой части света, а значит пользователи будут вводить числовые данные в элемент управления TextBox в самых разных форматах.Because a Web page can be displayed anywhere in the world, users can input numeric data into a TextBox control in an almost unlimited number of formats. Поэтому очень важно правильно определить язык и региональные параметры каждого посетителя веб-страницы.As a result, it is very important to determine the locale and culture of the Web page's user. Тогда вы сможете применить соглашения о форматировании, соответствующие языку и региональным параметрам пользователя, при синтаксическом анализе вводимых данных.When you parse user input, you can then apply the formatting conventions defined by the user's locale and culture.

Преобразование входных данных из элемента управления Web TextBox в числовое значениеTo convert numeric input from a Web TextBox control to a number

  1. Определите, заполнен ли массив строк, возвращаемый в свойстве HttpRequest.UserLanguages.Determine whether the string array returned by the HttpRequest.UserLanguages property is populated. Если нет, перейдите к шагу 6.If it is not, continue to step 6.

  2. Если массив строк, возвращаемый в свойстве UserLanguages, заполнен, извлеките его первый элемент.If the string array returned by the UserLanguages property is populated, retrieve its first element. Первый элемент определяет язык и регион, установленные для пользователя по умолчанию или выбранные им в настройках.The first element indicates the user's default or preferred language and region.

  3. Создайте экземпляр объекта CultureInfo, который представляет выбранные пользователем язык и региональные параметры, вызвав конструктор CultureInfo.CultureInfo(String, Boolean).Instantiate a CultureInfo object that represents the user's preferred culture by calling the CultureInfo.CultureInfo(String, Boolean) constructor.

  4. Вызовите метод TryParse или Parse для числового типа, в который вы хотите преобразовать пользовательские данные.Call either the TryParse or the Parse method of the numeric type that you want to convert the user's input to. Используйте перегрузку метода TryParse или Parse с параметром provider и передайте в него один из следующих объектов:Use an overload of the TryParse or the Parse method with a provider parameter, and pass it either of the following:

  5. Если преобразование завершается сбоем, повторите шаги 2–4 поочередно для каждого из остальных элементов в массиве строк, полученных в свойстве UserLanguages.If the conversion fails, repeat steps 2 through 4 for each remaining element in the string array returned by the UserLanguages property.

  6. Если все преобразования завершатся сбоем или свойство UserLanguages вернет пустой массив строк, используйте для синтаксического анализа инвариантные язык и региональные параметры, которые возвращаются в свойстве CultureInfo.InvariantCulture.If the conversion still fails or if the string array returned by the UserLanguages property is empty, parse the string by using the invariant culture, which is returned by the CultureInfo.InvariantCulture property.

ПримерExample

Ниже приведен полный пример кода программной части для веб-формы, которая предлагает пользователю ввести числовое значение в элемент управления TextBox, а затем преобразует эти данные в число.The following example is the complete code-behind page for a Web form that asks the user to enter a numeric value in a TextBox control and converts it to a number. Затем программа удваивает полученное число и отображает его с использованием тех же правил форматирования, которые применялись для входных данных.That number is then doubled and displayed by using the same formatting rules as the original input.

using System;
using System.Globalization;

partial class NumericUserInput : System.Web.UI.Page
{
   protected void OKButton_Click(object sender, EventArgs e)
   {
      string locale;
      CultureInfo culture = null;
      double number = 0;
      bool result = false;

      // Exit if input is absent.
      if (String.IsNullOrEmpty(this.NumericString.Text)) return;

      // Hide form elements.
      this.NumericInput.Visible = false;

      // Get user culture/region
      if (!(Request.UserLanguages.Length == 0 || String.IsNullOrEmpty(Request.UserLanguages[0])))
      {
         try
         {
            locale = Request.UserLanguages[0];
            culture = new CultureInfo(locale, false);

            // Parse input using user culture.
            result = Double.TryParse(this.NumericString.Text, NumberStyles.Any,
                                     culture.NumberFormat, out number);
         }
         catch { }
         // If parse fails, parse input using any additional languages.
         if (!result)
         {
            if (Request.UserLanguages.Length > 1)
            {
               for (int ctr = 1; ctr <= Request.UserLanguages.Length - 1; ctr++)
               {
                  try
                  {
                     locale = Request.UserLanguages[ctr];
                     // Remove quality specifier, if present.
                     locale = locale.Substring(1, locale.IndexOf(';') - 1);
                     culture = new CultureInfo(Request.UserLanguages[ctr], false);
                     result = Double.TryParse(this.NumericString.Text, NumberStyles.Any, culture.NumberFormat, out number);
                     if (result) break;
                  }
                  catch { }
               }
            }
         }
      }
      // If parse operation fails, use invariant culture.
      if (!result)
         result = Double.TryParse(this.NumericString.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out number);

      // Double result.
      number *= 2;

      // Display result to user.
      if (result)
      {
         Response.Write("<P />");
         Response.Write(Server.HtmlEncode(this.NumericString.Text) + " * 2 = " + number.ToString("N", culture) + "<BR />");
      }
      else
      {
         // Unhide form.
         this.NumericInput.Visible = true;

         Response.Write("<P />");
         Response.Write("Unable to recognize " + Server.HtmlEncode(this.NumericString.Text));
      }
   }
}
Imports System.Globalization

Partial Class NumericUserInput
   Inherits System.Web.UI.Page

   Protected Sub OKButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles OKButton.Click
      Dim locale As String
      Dim culture As CultureInfo = Nothing
      Dim number As Double
      Dim result As Boolean

      ' Exit if input is absent.
      If String.IsNullOrEmpty(Me.NumericString.Text) Then Exit Sub

      ' Hide form elements.
      Me.NumericInput.Visible = False

      ' Get user culture/region
      If Not (Request.UserLanguages.Length = 0 OrElse String.IsNullOrEmpty(Request.UserLanguages(0))) Then
         Try
            locale = Request.UserLanguages(0)
            culture = New CultureInfo(locale, False)

            ' Parse input using user culture.
            result = Double.TryParse(Me.NumericString.Text, NumberStyles.Any, culture.NumberFormat, number)
         Catch
         End Try
         ' If parse fails, parse input using any additional languages.
         If Not result Then
            If Request.UserLanguages.Length > 1 Then
               For ctr As Integer = 1 To Request.UserLanguages.Length - 1
                  Try
                     locale = Request.UserLanguages(ctr)
                     ' Remove quality specifier, if present.
                     locale = Left(locale, InStr(locale, ";") - 1)
                     culture = New CultureInfo(Request.UserLanguages(ctr), False)
                     result = Double.TryParse(Me.NumericString.Text, NumberStyles.Any, culture.NumberFormat, number)
                     If result Then Exit For
                  Catch
                  End Try
               Next
            End If
         End If
      End If
      ' If parse operation fails, use invariant culture.
      If Not result Then
         result = Double.TryParse(Me.NumericString.Text, NumberStyles.Any, CultureInfo.InvariantCulture, number)
      End If
      ' Double result
      number *= 2

      ' Display result to user.
      If result Then
         Response.Write("<P />")
         Response.Write(Server.HtmlEncode(Me.NumericString.Text) + " * 2 = " + number.ToString("N", culture) + "<BR />")
      Else
         ' Unhide form.
         Me.NumericInput.Visible = True

         Response.Write("<P />")
         Response.Write("Unable to recognize " + Server.HtmlEncode(Me.NumericString.Text))
      End If
   End Sub   
End Class

Свойство HttpRequest.UserLanguages заполняется именами языков и региональных параметров из заголовков Accept-Language, включенных в HTTP-запрос.The HttpRequest.UserLanguages property is populated from the culture names that are contained in Accept-Language headers included in an HTTP request. Но не все браузеры включают в запрос заголовки Accept-Language, а пользователь может принудительно запретить такие заголовки.However, not all browsers include Accept-Language headers in their requests, and users can also suppress the headers completely. Это означает, что для синтаксического анализа введенных пользователем данных требуется наличие языка и региональных параметров по умолчанию.This makes it important to have a fallback culture when parsing user input. Обычно в таких случаях используются инвариантные язык и региональные параметры, возвращаемые в свойстве CultureInfo.InvariantCulture.Typically, the fallback culture is the invariant culture returned by CultureInfo.InvariantCulture. В Internet Explorer пользователи могут вводить имена языков и региональных стандартов в обычное текстовое поле, а значит эти имена могут оказаться недопустимыми.Users can also provide Internet Explorer with culture names that they input in a text box, which creates the possibility that the culture names may not be valid. Поэтому при создании экземпляра объекта CultureInfo необходимо обрабатывать исключения.This makes it important to use exception handling when instantiating a CultureInfo object.

Массив HttpRequest.UserLanguages заполняется данными, извлеченными из HTTP-запроса, полученного от Internet Explorer, в порядке пользовательских предпочтений.When retrieved from an HTTP request submitted by Internet Explorer, the HttpRequest.UserLanguages array is populated in order of user preference. Первый элемент массива содержит основное имя региона или языка и региональных параметров пользователя.The first element in the array contains the name of the user's primary culture/region. Если массив содержит другие элементы, Internet Explorer в произвольном порядке присваивает им описатели качества, отделенные от имени языка и региональных параметров точкой с запятой.If the array contains any additional items, Internet Explorer arbitrarily assigns them a quality specifier, which is delimited from the culture name by a semicolon. Например, запись для языка и региональных параметров fr-FR может принять форму fr-FR;q=0.7.For example, an entry for the fr-FR culture might take the form fr-FR;q=0.7.

Этот пример вызывает конструктор CultureInfo, присваивая параметру useUserOverride значение false, чтобы создать объект CultureInfo.The example calls the CultureInfo constructor with its useUserOverride parameter set to false to create a new CultureInfo object. Это означает, что если используется стандартное для сервера имя языка и региональных параметров, конструктор класса создает объект CultureInfo с региональными параметрами по умолчанию без учета настроек, указанных на сервере в приложении Язык и региональные стандарты.This ensures that, if the culture name is the default culture name on the server, the new CultureInfo object created by the class constructor contains a culture's default settings and does not reflect any settings overridden by using the server's Regional and Language Options application. Маловероятно, что измененные в настройках сервера значения будут сохранены на компьютере пользователя или учтены при вводе данных.The values from any overridden settings on the server are unlikely to exist on the user's system or to be reflected in the user's input.

Вы можете вызвать метод Parse или TryParse для того числового типа, в который вы намерены преобразовать введенные данные.Your code can call either the Parse or the TryParse method of the numeric type that the user's input will be converted to. Для одной операции синтаксического анализа может потребоваться несколько вызовов метода parse.Repeated calls to a parse method may be required for a single parsing operation. А значит, метод TryParse предпочтителен, ведь при сбое операции синтаксического анализа он возвращает false.As a result, the TryParse method is better, because it returns false if a parse operation fails. Обработка же нескольких исключений, которые могут быть созданы в методе Parse, потребует больших затрат при выполнении веб-приложения.In contrast, handling the repeated exceptions that may be thrown by the Parse method can be a very expensive proposition in a Web application.

Компиляция кодаCompiling the Code

Чтобы скомпилировать код, скопируйте его в файл кода программной части ASP.NET, заменив этим текстом весь существующий код.To compile the code, copy it into an ASP.NET code-behind page so that it replaces all the existing code. Веб страница ASP.NET должна содержать следующие элементы управления:The ASP.NET Web page should contain the following controls:

  • элемент управления Label, который не указан в кодеA Label control, which is not referenced in code. (для его свойства Text задайте значение "Введите число:");Set its Text property to "Enter a Number:".

  • элемент управления TextBox с именем NumericString;A TextBox control named NumericString.

  • элемент управления Button с именем OKButton;A Button control named OKButton. (для его свойства Text задайте значение "ОК").Set its Text property to "OK".

Замените имя класса NumericUserInput именем класса, которое определено в атрибуте Inherits директивы Page страницы ASP.NET.Change the name of the class from NumericUserInput to the name of the class that is defined by the Inherits attribute of the ASP.NET page's Page directive. Замените имя ссылки на объект NumericInput именем, которое определено в атрибуте id тега form страницы ASP.NET.Change the name of the NumericInput object reference to the name defined by the id attribute of the ASP.NET page's form tag.

Безопасность платформы .NET Framework.NET Framework Security

Чтобы пользователи не могли внедрять скрипты в поток HTML, никогда не передавайте введенные данные напрямую в ответе сервера.To prevent a user from injecting script into the HTML stream, user input should never be directly echoed back in the server response. Всегда шифруйте ответ с помощью метода HttpServerUtility.HtmlEncode.Instead, it should be encoded by using the HttpServerUtility.HtmlEncode method.

См. такжеSee also