none
一个奇怪的 ajax 里的 类型转换问题 RRS feed

  • 问题

  • 有这样一个页面程序
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title></title>
    </head>
    <script runat="server" language="C#">
                protected void Page_Load(object sender, EventArgs e)
            {
                if (!Page.IsPostBack)
                {
                    System.Data.DataTable dt = new System.Data.DataTable("Product");

                    dt.Columns.Add(new System.Data.DataColumn("PID"));
                    dt.Columns.Add(new System.Data.DataColumn("PName"));
                    dt.Columns.Add(new System.Data.DataColumn("PPrice"));

                    System.Data.DataRow dr;
                    for (int i = 0; i < 5; i++)
                    {
                        dr = dt.NewRow();
                        dr["PID"] = i;
                        dr["PName"] = i;
                        dr["PPrice"] = i;

                        dt.Rows.Add(dr);
                    }

                    dlTest.DataSource = dt;
                    dlTest.DataBind();
                }
            }

            protected void TextBox1_TextChanged(object sender, EventArgs e)
            {
                for (int i = 0; i < dlTest.Items.Count; i++)
                {
                    TextBox tb = (TextBox)dlTest.Items[i].FindControl("txtPrice");

                    double price = Convert.ToDouble(TextBox1.Text);
                    tb.Text = price.ToString();
                }
            }
    </script>
    <body>
        <form id="form1" runat="server">
        <div>   
            <asp:TextBox ID="TextBox1" runat="server" ontextchanged="TextBox1_TextChanged"
                AutoPostBack="True"></asp:TextBox>
            <asp:ScriptManager ID="ScriptManager1" runat="server">
            </asp:ScriptManager>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>             
        <asp:DataList ID="dlTest" runat="server" RepeatColumns="6" RepeatDirection="Horizontal" Width="95%">
                  <ItemTemplate>
                       <table width="100%">
                          <tr>
                              <td align="center"><table width="100%">
                                    <tr><td align="center"><asp:Label ID="labPID" runat="server" Text='<%#Eval("PID") %>' Visible = "false"></asp:Label>
                                        <asp:Label ID="labPName" runat="server" Text='<%#Eval("PName") %>'></asp:Label>
                                    </td></tr>
                                    <tr>
                                        <td align="center"><asp:Label ID="labPriceYY" runat="server" Text='<%#Eval("PPrice") %>' Visible = "false"></asp:Label>
                                            Price:&nbsp;<asp:TextBox ID="txtPrice" runat="server" Width="50" Text='<%#Eval("PPrice") %>'></asp:TextBox>&nbsp;€
                                        </td>
                                    </tr>
                                    <tr><td></td></tr>
                                    </table>                             
                               </td>
                          </tr>
                        </table>
                  </ItemTemplate>
                  <AlternatingItemStyle BackColor="#F7F7F7" />
                  <ItemStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" VerticalAlign="Bottom" Height="100%"/>
                  <SelectedItemStyle BackColor="#738A9C" ForeColor="#F7F7F7" Font-Bold="True" />
                  <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#F7F7F7" />
               </asp:DataList>
                </ContentTemplate>
            </asp:UpdatePanel>
       
        </div>
        </form>
    </body>
    </html>




    使用的是 Windows server 2008

    当使用 Version Information: Microsoft .NET Framework Version:2.0.50727.3053; ASP.NET Version:2.0.50727.3053

    double price = Convert.ToDouble(TextBox1.Text);
    这句是正常的。


    但当使用 版本信息: Microsoft .NET Framework 版本:2.0.50727.3074; ASP.NET 版本:2.0.50727.3074
    时 , 当
    TextBox1.Text 的内容为 int 时是正确, 而内容为小数时就出错

    堆栈跟踪:

    [FormatException: 输入字符串的格式不正确。]
    
       System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) +7469351
    
       System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt) +146
    
       System.Convert.ToDecimal(String value) +83
    
    


    或者怎么能把版本: Microsoft .NET Framework 版本:2.0.50727.3074; ASP.NET 版本:2.0.50727.3074
    降到
    Version Information: Microsoft .NET Framework Version:2.0.50727.3053; ASP.NET Version:2.0.50727.3053


    谢谢了

    2009年7月8日 16:34

答案

  • <%@ Page Language="C#" AutoEventWireup="true" CodeFile="X200907090918.aspx.cs" Inherits="HTML_CSS_JAVASCRIPT_X200907090918" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
        <title></title>
    </head>
    <script runat="server" language="C#">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                System.Data.DataTable dt = new System.Data.DataTable("Product");
    
                dt.Columns.Add(new System.Data.DataColumn("PID"));
                dt.Columns.Add(new System.Data.DataColumn("PName"));
                dt.Columns.Add(new System.Data.DataColumn("PPrice"));
    
                System.Data.DataRow dr;
                for (int i = 0; i < 5; i++)
                {
                    dr = dt.NewRow();
                    dr["PID"] = i;
                    dr["PName"] = i;
                    dr["PPrice"] = i;
    
                    dt.Rows.Add(dr);
                }
    
                dlTest.DataSource = dt;
                dlTest.DataBind();
            }
        }
    
        protected void TextBox1_TextChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < dlTest.Items.Count; i++)
            {
                TextBox tb = (TextBox)dlTest.Items[i].FindControl("txtPrice");
    
                double price = Convert.ToDouble(TextBox1.Text);
                tb.Text = price.ToString();
            }
        }
    </script>
    <body>
        <form id="form2" runat="server">
        <div>    
            <asp:TextBox ID="TextBox1" runat="server" onkeypress="AllowInputNumber();" ontextchanged="TextBox1_TextChanged" AutoPostBack="True"></asp:TextBox>
            <script type="text/javascript">
            // 限制用户只能输入数字
            function AllowInputNumber(){
               if(!(((window.event.keyCode >= 48) && (window.event.keyCode <= 57)) 
                        || (window.event.keyCode == 13) || (window.event.keyCode == 46) 
                        || (window.event.keyCode == 45))){
                        window.event.keyCode = 0;
                }
            }
            
            </script>
            <asp:ScriptManager ID="ScriptManager1" runat="server">
            </asp:ScriptManager>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>              
                  <asp:DataList ID="dlTest" runat="server" RepeatColumns="6" RepeatDirection="Horizontal" Width="95%">
                  <ItemTemplate>
                       <table width="100%">
                          <tr>
                              <td align="center"><table width="100%">
                                    <tr><td align="center"><asp:Label ID="labPID" runat="server" Text='<%#Eval("PID") %>' Visible = "false"></asp:Label>
                                        <asp:Label ID="labPName" runat="server" Text='<%#Eval("PName") %>'></asp:Label>
                                    </td></tr>
                                    <tr>
                                        <td align="center"><asp:Label ID="labPriceYY" runat="server" Text='<%#Eval("PPrice") %>' Visible = "false"></asp:Label>
                                            Price:&nbsp;<asp:TextBox ID="txtPrice" runat="server" Width="50" Text='<%#Eval("PPrice") %>'></asp:TextBox>&nbsp;€
                                        </td>
                                    </tr>
                                    <tr><td></td></tr>
                                    </table>                              
                               </td>
                          </tr>
                        </table>
                  </ItemTemplate>
                  <AlternatingItemStyle BackColor="#F7F7F7" />
                  <ItemStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" VerticalAlign="Bottom" Height="100%"/>
                  <SelectedItemStyle BackColor="#738A9C" ForeColor="#F7F7F7" Font-Bold="True" />
                  <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#F7F7F7" />
               </asp:DataList>
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
        </form>
    </body>
    </html>
    

    知识改变命运,奋斗成就人生!
    2009年7月9日 1:25
    版主
  • 还可以对其进行异常捕获,然后提示用户....
    protected void TextBox1_TextChanged(object sender, EventArgs e)
                    {
                        for (int i = 0; i < dlTest.Items.Count; i++)
                        {
                            TextBox tb = (TextBox)dlTest.Items[i].FindControl("txtPrice");
                            try
                            {
                                double price = Convert.ToDouble(TextBox1.Text);
                                tb.Text = price.ToString();
                            }
                            catch
                            {
                                ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alert", "alert('您输入了非法字符!')", true);
                            }
                        }
                    }
    2009年7月9日 1:40

全部回复

  • 我用您的代码,输入小数没有问题。请检查一下是否将小数点录成句号了。

    2009年7月8日 17:09
    版主
  • <%@ Page Language="C#" AutoEventWireup="true" CodeFile="X200907090918.aspx.cs" Inherits="HTML_CSS_JAVASCRIPT_X200907090918" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
        <title></title>
    </head>
    <script runat="server" language="C#">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                System.Data.DataTable dt = new System.Data.DataTable("Product");
    
                dt.Columns.Add(new System.Data.DataColumn("PID"));
                dt.Columns.Add(new System.Data.DataColumn("PName"));
                dt.Columns.Add(new System.Data.DataColumn("PPrice"));
    
                System.Data.DataRow dr;
                for (int i = 0; i < 5; i++)
                {
                    dr = dt.NewRow();
                    dr["PID"] = i;
                    dr["PName"] = i;
                    dr["PPrice"] = i;
    
                    dt.Rows.Add(dr);
                }
    
                dlTest.DataSource = dt;
                dlTest.DataBind();
            }
        }
    
        protected void TextBox1_TextChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < dlTest.Items.Count; i++)
            {
                TextBox tb = (TextBox)dlTest.Items[i].FindControl("txtPrice");
    
                double price = Convert.ToDouble(TextBox1.Text);
                tb.Text = price.ToString();
            }
        }
    </script>
    <body>
        <form id="form2" runat="server">
        <div>    
            <asp:TextBox ID="TextBox1" runat="server" onkeypress="AllowInputNumber();" ontextchanged="TextBox1_TextChanged" AutoPostBack="True"></asp:TextBox>
            <script type="text/javascript">
            // 限制用户只能输入数字
            function AllowInputNumber(){
               if(!(((window.event.keyCode >= 48) && (window.event.keyCode <= 57)) 
                        || (window.event.keyCode == 13) || (window.event.keyCode == 46) 
                        || (window.event.keyCode == 45))){
                        window.event.keyCode = 0;
                }
            }
            
            </script>
            <asp:ScriptManager ID="ScriptManager1" runat="server">
            </asp:ScriptManager>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>              
                  <asp:DataList ID="dlTest" runat="server" RepeatColumns="6" RepeatDirection="Horizontal" Width="95%">
                  <ItemTemplate>
                       <table width="100%">
                          <tr>
                              <td align="center"><table width="100%">
                                    <tr><td align="center"><asp:Label ID="labPID" runat="server" Text='<%#Eval("PID") %>' Visible = "false"></asp:Label>
                                        <asp:Label ID="labPName" runat="server" Text='<%#Eval("PName") %>'></asp:Label>
                                    </td></tr>
                                    <tr>
                                        <td align="center"><asp:Label ID="labPriceYY" runat="server" Text='<%#Eval("PPrice") %>' Visible = "false"></asp:Label>
                                            Price:&nbsp;<asp:TextBox ID="txtPrice" runat="server" Width="50" Text='<%#Eval("PPrice") %>'></asp:TextBox>&nbsp;€
                                        </td>
                                    </tr>
                                    <tr><td></td></tr>
                                    </table>                              
                               </td>
                          </tr>
                        </table>
                  </ItemTemplate>
                  <AlternatingItemStyle BackColor="#F7F7F7" />
                  <ItemStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" VerticalAlign="Bottom" Height="100%"/>
                  <SelectedItemStyle BackColor="#738A9C" ForeColor="#F7F7F7" Font-Bold="True" />
                  <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#F7F7F7" />
               </asp:DataList>
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
        </form>
    </body>
    </html>
    

    知识改变命运,奋斗成就人生!
    2009年7月9日 1:25
    版主
  • 还可以对其进行异常捕获,然后提示用户....
    protected void TextBox1_TextChanged(object sender, EventArgs e)
                    {
                        for (int i = 0; i < dlTest.Items.Count; i++)
                        {
                            TextBox tb = (TextBox)dlTest.Items[i].FindControl("txtPrice");
                            try
                            {
                                double price = Convert.ToDouble(TextBox1.Text);
                                tb.Text = price.ToString();
                            }
                            catch
                            {
                                ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alert", "alert('您输入了非法字符!')", true);
                            }
                        }
                    }
    2009年7月9日 1:40
  • 不好意思, 昨天回学校有事所以就没上网 :)

    我加了那个 AllowInputNumber() 的判断, 还是同样的错误


    我用的是 Windows 2008 ,

    .NET 的版本信息是 Microsoft .NET Framework 版本:2.0.50727.3074; ASP.NET 版本:2.0.50727.3074



    我在另一台机器 安装 Windows 2008, 使用
    Version Information: Microsoft .NET Framework Version:2.0.50727.3053; ASP.NET Version:2.0.50727.3053


    结果就是正常的。

    2009年7月10日 7:10
  • 我在本机用的 XP, 使用 Microsoft .NET Framework Version:2.0.50727.3053; ASP.NET Version:2.0.50727.3053 也是正常的。


    工作用是 Windows 2008 ,

    .NET 的版本信息是 Microsoft .NET Framework 版本:2.0.50727.3074; ASP.NET 版本:2.0.50727.3074
    就出错,




    我在另一台机器 安装 Windows 2008, 使用
    Version Information: Microsoft .NET Framework Version:2.0.50727.3053; ASP.NET Version:2.0.50727.3053


    结果就是正常的。



    公司的网管把自动升级开着, 也不知道是那个补丁把 3053 升到了 3074 , 如果能把那个补丁卸掉也是一种解决办法。



    谢谢了

    2009年7月10日 7:14
  • 谢谢大家, 找到问题了, 是多语言的问题,是中法小数点的不同引起的


    中国的小数这样写 3.14
    法国的小数是 3,14


    请问怎么写个程序避免
    double price = Convert.ToDouble(tb.Text);

    出错,


    我已经把法语系统 上的语言, 区域设置都改成了 中文, 可是还不行。。。。。。。。。


    谢谢了

    2009年7月10日 9:40
  • 将, 号替换成 .
    知识改变命运,奋斗成就人生!
    2009年7月10日 9:42
    版主
  • 如果简单替换一下, 那在中文系统上就会出错。。。。。。。。。。。。
    2009年7月10日 9:56
  • 可以通过正则判断一下,不合法就给用户提示重新输入
    知识改变命运,奋斗成就人生!
    2009年7月10日 9:58
    版主
  • 与用户输入没有关系, 是由多语言环境决定的



    总算可以了, 使用这个就行了

    double price = double.Parse("3.14", (new CultureInfo("zh-CN")).NumberFormat);


    中法文环境都不会出错 :)




    谢谢了:)
    2009年7月10日 10:09
  • 晕倒,一个多语言的问题。您没告诉我们隐含的使用背景,这上哪猜去!
    好在问题已解决
    2009年7月11日 10:57
    版主