共用方式為


HOW TO:將使用者輸入 Web 控制項的數值轉換成數字

由於網頁可在任何地方顯示,因此使用者可在 TextBox 控制項中輸入幾乎無限多種格式的數值。 所以,務必決定網頁使用者的地區設定和文化特性。 當您剖析使用者輸入時,就可以接著套用使用者地區設定和文化特性定義的格式化慣例。

將 Web TextBox 控制項的數值輸入轉換成數字

  1. 判斷 HttpRequest.UserLanguages 屬性傳回的字串陣列是否已填入。 如果尚未填入,則繼續進行步驟 6。

  2. 如果 UserLanguages 屬性所傳回的字串陣列已填入,就會擷取它的第一個項目。 第一個項目指出使用者的預設或慣用的語言和區域。

  3. 呼叫 CultureInfo.CultureInfo(String, Boolean) 建構函式以具現化 CultureInfo 物件,此物件代表使用者慣用的文化特性。

  4. 呼叫要將使用者輸入轉換成之數值型別的 TryParse 或 Parse 方法。 使用 TryParse 或 Parse 方法的多載與 provider 參數,並將下列任一項傳遞給該多載:

  5. 如果轉換失敗,則針對 UserLanguages 屬性傳回的字串陣列中其餘每一個項目重複步驟 2 到 4。

  6. 如果轉換還是失敗,或者,如果 UserLanguages 屬性所傳回的字串陣列為空白,請使用由 CultureInfo.InvariantCulture 屬性所傳回的 Invariant 文化特性 (不因文化特定而異) 來剖析字串。

範例

以下範例是 Web Form 的完整程式碼後置頁,會要求使用者在 TextBox 控制項中輸入數值,並將它轉換成數字。 接著該數字會加倍,並且使用與原始輸入相同的格式化規則顯示。

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
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));
      }
   }
}

HttpRequest.UserLanguages 屬性會從 HTTP 要求所包含 Accept-Language 標頭中的文化特性名稱填入。 不過,並非所有瀏覽器的要求都包含 Accept-Language 標頭,而且使用者可以完全隱藏標頭。 因此,剖析使用者輸入時務必有後援文化特性。 通常後援文化特性是 CultureInfo.InvariantCulture 傳回的不因國別而異的文化特性。 使用者也可以將文字方塊中輸入的文化特性名稱提供給 Internet Explorer,如此可能讓文化特性名稱無效。 因此具現化 CultureInfo 物件時,務必使用例外處理。

從 Internet Explorer 提交的 HTTP 要求擷取時,HttpRequest.UserLanguages 陣列會依使用者偏好設定填入。 陣列中的第一個項目包含使用者主要文化特性/區域的名稱。 如果陣列包含任何額外的項目,Internet Explorer 會為這些項目指派任意限定規範,並且使用分號與文化特性名稱分隔。 例如,fr-FR 文化特性的項目可能採用這個格式 fr-FR;q=0.7。

範例會呼叫 CultureInfo 建構函式,且其 useUserOverride 參數會設為 false,以建立新的 CultureInfo 物件。 如此可確定,如果文化特性名稱是伺服器上預設的文化特性名稱,則類別建構函式建立的 CultureInfo 物件會包含文化特性的預設設定,並且不會反映使用伺服器的 [地區及語言選項] 應用程式覆寫的任何設定。 伺服器上任何覆寫設定的值都不會出現在使用者的系統上,或是反映在使用者輸入中。

您的程式碼可以呼叫使用者輸入將轉換成的數值型別之 Parse 或 TryParse 方法。 您可能需要針對單一剖析作業重複呼叫剖析方法。 因此 TryParse 方法可能較佳,因為它會在剖析作業失敗時傳回 false。 相反地,對於 Web 應用程式而言,處理 Parse 方法可能擲回的重複例外狀況可能是相當耗費資源的方法。

編譯程式碼

若要編譯程式碼,請將它複製到 ASP.NET 程式碼後置頁,以取代所有現有的程式碼。 ASP.NET 網頁應包含下列控制項:

  • Label 控制項,程式碼中並未參考這個控制項。 將 Text 屬性設為 [輸入數字:]。

  • 名為 NumericString 的 TextBox 控制項。

  • 名為 OKButton 的 Button 控制項。 將 Text 屬性設為 [確定]。

將類別的名稱從 NumericUserInput 變更為 ASP.NET 頁面之 Page 指示詞的 Inherits 屬性所定義的類別名稱。 接著,將 NumericInput 物件參考的名稱變更為 ASP.NET 頁面之 form 標記的 id 屬性所定義的名稱。

安全性

為避免使用者將指令碼插入 HTML 資料流中,絕不可將使用者輸入直接回應 (Echo) 至伺服器回應中。 而是使用 HttpServerUtility.HtmlEncode 方法將使用者輸入編碼。

請參閱

概念

執行格式化作業

剖析數值字串