1

更新

我发现了问题,异常来自同一表单上的第二个字段,它确实应该提示它(因为它是空的)......我正在查看一个我认为来自尝试解析一个字符串的错误,事实上,它是因为试图解析另一个字符串......抱歉浪费你的时间。

原始问题

我完全被这个问题弄傻了。我基本上是在跑步int.Parse("32"),它会抛出一个FormatException. 这是有问题的代码:

private double BindGeo(string value)
{
    Regex r = new Regex(@"\D*(?<deg>\d+)\D*(?<min>\d+)\D*(?<sec>\d+(\.\d*))");
    Regex d = new Regex(@"(?<dir>[NSEW])");
    var numbers = r.Match(value);
    string degStr = numbers.Groups["deg"].ToString();
    string minStr = numbers.Groups["min"].ToString();
    string secStr = numbers.Groups["sec"].ToString();
    Debug.Assert(degStr == "32");
    var deg = int.Parse(degStr);
    var min = int.Parse(minStr);
    var sec = double.Parse(secStr);
    var direction = d.Match(value).Groups["dir"].ToString();
    var result = deg + (min / 60.0) + (sec / 3600.0);
    if (direction == "S" || direction == "W") result = -result;
    return result;
}

我的输入字符串是"32 19 17.25 N"

上述代码在 ASP.NET MVC 3 Web 应用程序(使用 Razor 作为其视图引擎)上的 .NET 4 Web 托管服务 (aspspider) 上运行。

注意的断言degStr == "32"是有效的!此外,当我采用上述代码并在控制台应用程序中运行它时,它工作得很好。我在网上搜索了答案,没有...

有任何想法吗?

更新(堆栈跟踪)

[FormatException: Input string was not in a correct format.]
   System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) +9586043
   System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) +119
   System.Int32.Parse(String s) +23
   ParkIt.GeoModelBinder.BindGeo(String value) in C:\MyProjects\ParkIt\ParkIt\GeoBinder.cs:42

第 42 行是var deg = int.Parse(degStr);并注意异常在System.Int32.Parse(不是System.Double建议的那样)。

4

4 回答 4

3

您错误地认为引发异常的是以下行:

int.Parse("32")

这条线不太可能抛出异常。

事实上它是以下行:

var sec = double.Parse(secStr);

在这种情况下secStr = "17.25";

原因是您的托管服务提供商使用不同的文化,其中.不是小数分隔符。

您可以在 web.config 文件中指定文化:

<globalization culture="en-US" uiCulture="en-US" />

如果您不这样做,则auto使用 then 。这意味着可以根据客户端浏览器首选项设置文化(使用 Accept-Language HTTP 标头随每个请求一起发送)。

另一种可能性是在解析时指定文化:

var sec = double.Parse(secStr, CultureInfo.InvariantCulture);

这样您就可以确定这.是不变文化的小数分隔符。

于 2012-05-02T09:06:53.103 回答
2

测试这个(通过 PowerShell):

PS [64] E:\dev #43> '32 19 17.25 N' -match "\D*(?\d+)\D*(?\d+)\D*(?\d+(\.\d*) )"
真的
PS [64] E:\dev #44> $Matches

名称 值
---- -----
17.25 秒
度 32
19 分钟
1 .25
0 32 19 17.25

因此,正则表达式正在使用所有三个命名捕获获取一个值,所有这些都将解析 OK(即,它不像\d匹配 U+0660: ARABIC-INDIC DIGIT ZERO 之类的东西,Int32.Parse无法处理)。

但是您不检查正则表达式是否确实匹配。

因此我怀疑value传递给函数的不是您期望的输入。在函数的开头放置一个断点(或日志记录)并获取value.

我认为正在发生的事情是:

  • Value不是你想的那样。
  • 正则表达式无法匹配。
  • 捕获是空的
  • Int32.Parse("")正在抛出(刚刚确认:它抛出 FormatException “输入字符串的格式不正确。”)

附录:刚刚注意到你对断言的评论。

如果事情看起来矛盾,回到基础:至少你的一个假设是错误的,例如。异常的行号中可能有一个减一(在转到该行号之前对文件进行编辑:很容易做到)。

在这种情况下,使用调试器单步执行是迄今为止最简单的方法。在每个表达式上检查一切

如果您不能使用调试器,请尝试删除该限制,如果不是,IntelliTrace 怎么样?Othewrwise 使用某种日志记录(如果您的应用程序没有它,请添加它,因为您将来需要它来处理此类事情)。

于 2012-05-02T10:24:05.173 回答
1

尝试从字符串中删除非 unicode(如果有的话 - 不可见)字符:

string s = "søme string";
s = Regex.Replace(s, @"[^\u0000-\u007F]", string.Empty);

编辑

另外 - 尝试查看它的十六进制值以查看它在哪里执行异常:

BitConverter.ToString(buffer);

这将向您显示十六进制值,以便您验证...

还要粘贴它的值,以便我们看到它。

于 2012-05-02T09:58:13.107 回答
0

事实证明,这是一个非问题。问题是异常来自同一表单上的第二个字段,它确实应该提示它(因为它是空的)......我正在查看一个我认为来自尝试解析一个字符串的错误,而事实上这是因为试图解析另一个字符串...

很抱歉浪费您的时间。

于 2012-05-02T11:05:37.000 回答