如何确定哪个元素导致溢出?

时间:2015-01-07 18:25:02

标签: c# visual-studio-debugging parseint int32 overflowexception

我有这段代码:

String testData = File.ReadAllText("siteQueryTest.txt");
XDocument xmlDoc = XDocument.Parse(testData);
List<SiteQuery> sitequeries =
 (from sitequery in xmlDoc.Descendants("SiteQuery")
  select new SiteQuery
  {
      Id = Convert.ToInt32(sitequery.Element("Id").Value),
      UPCPackSize = Convert.ToInt32(sitequery.Element("UPCPackSize").Value),
      UPC_Code = sitequery.Element("UPC_Code").Value,
      crvId = sitequery.Element("crvId").Value,
      dept = Convert.ToInt32(sitequery.Element("dept").Value),
      description = sitequery.Element("description").Value,
      openQty = Convert.ToDouble(sitequery.Element("openQty").Value),
      packSize = Convert.ToInt32(sitequery.Element("packSize").Value),
      subDept = Convert.ToInt32(sitequery.Element("subDept").Value),
      unitCost = Convert.ToDecimal(sitequery.Element("unitCost").Value),
      unitList = Convert.ToDecimal(sitequery.Element("unitList").Value),
      vendorId = sitequery.Element("vendorId").Value,
      vendorItem = sitequery.Element("vendorItem").Value,
  }).ToList<SiteQuery>();

testData是:

<SiteQueries><SiteQuery><Id>00006000002</Id><UPCPackSize>1</UPCPackSize><UPC_Code>00006000002</UPC_Code><crvId></crvId><dept>8</dept><description>ZZ</description><openQty>0.0</openQty><packSize>1</packSize><subDept>80</subDept><unitCost>1.25</unitCost><unitList>5.0</unitList><vendorId>CONFLICT</vendorId><vendorItem>123456</vendorItem></SiteQuery>
. . . // gazillions of other SiteQuery "records"
<SiteQuery><Id>5705654</Id><UPCPackSize>1</UPCPackSize><UPC_Code>5705654</UPC_Code><crvId></crvId><dept>2</dept><description>what do you want</description><openQty>0.0</openQty><packSize>1</packSize><subDept>0</subDept><unitCost>0.55</unitCost><unitList>1.62</unitList><vendorId></vendorId><vendorItem></vendorItem></SiteQuery></SiteQueries>

但是我用这段代码和数据得到了以下运行时异常:

System.OverflowException was unhandled
  _HResult=-2146233066
  _message=Value was either too large or too small for an Int32.
  HResult=-2146233066
  IsTransient=false
  Message=Value was either too large or too small for an Int32.
  Source=mscorlib
  StackTrace:
       at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
       at System.Convert.ToInt32(String value)
       at Sandbox.Form1.<button56_Click>b__e(XElement sitequery) in c:\HoldingTank\Sandbox\Form1.cs:line 2041
       at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
    . . .
  InnerException: 

每个xml“记录”中有几个int值(4);有成千上万的记录。如果不试图穿上Rainman帽子(这对我来说不合适),我怎么能确定导致溢出或下溢的问题是哪个值?

如果它是下溢(异常msg表示“OverflowException”和“Value对于Int32来说太大或太小”),是否可能由这四个int成员之一的空值引起?如果是,我如何告诉它将空值视为0?

2 个答案:

答案 0 :(得分:4)

这就是大多数编码人员最终使用扩展方法而不是LINQ的原因。改写为:

private static SiteQuery ParseSiteQuery(XElement sitequery)
{
  return new SiteQuery
  {
      Id = Convert.ToInt32(sitequery.Element("Id").Value),
      UPCPackSize = Convert.ToInt32(sitequery.Element("UPCPackSize").Value),
      UPC_Code = sitequery.Element("UPC_Code").Value,
      crvId = sitequery.Element("crvId").Value,
      dept = Convert.ToInt32(sitequery.Element("dept").Value),
      description = sitequery.Element("description").Value,
      openQty = Convert.ToDouble(sitequery.Element("openQty").Value),
      packSize = Convert.ToInt32(sitequery.Element("packSize").Value),
      subDept = Convert.ToInt32(sitequery.Element("subDept").Value),
      unitCost = Convert.ToDecimal(sitequery.Element("unitCost").Value),
      unitList = Convert.ToDecimal(sitequery.Element("unitList").Value),
      vendorId = sitequery.Element("vendorId").Value,
      vendorItem = sitequery.Element("vendorItem").Value,
  };
}

然后再做

List<SiteQuery> sitequeries = xmlDoc.Descendants("SiteQuery")
                                    .Select(ParseSiteQuery).ToList();

现在,当异常发生时,您将在此转换函数内部进行分析,范围为sitequery,可以立即了解导致失败的特定XElement。

然后,您可以使用quickwatch表达式快速找出导致异常的初始化程序。甚至为每个属性赋值编写单独的语句。

答案 1 :(得分:0)

这就是最终的工作:

   private void button42_Click(object sender, EventArgs e)
   {
       ArrayList arrList = 
    FetchSiteQuery("http://localhost:21608/api/sitequery/getall/dbill/ppus/42"); 
        String omnivore = "<SiteQueries>";
        foreach (String s in arrList) //- see siteQueryData.png
        {
            omnivore += s;
        }
        omnivore += "</SiteQueries>";

        String messedUpJunk = "<ArrayOfSiteQuery xmlns:i=\"http://www.w3.org/2001/XMLSchema-
    instance\" xmlns=\"http://schemas.datacontract.org/2004/07/CStore.DomainModels.HHS\">";
        omnivore = omnivore.Replace(messedUpJunk, String.Empty);
        omnivore = omnivore.Replace("</ArrayOfSiteQuery>", String.Empty);

        XDocument xmlDoc = XDocument.Parse(omnivore);
        List<SiteQuery> sitequeries = 
    xmlDoc.Descendants("SiteQuery").Select(GetSiteQueryForXMLElement).ToList();
    }

    private static SiteQuery GetSiteQueryForXMLElement(XElement sitequery)
    {
        return new SiteQuery
        {
            Id = sitequery.Element("Id").Value,
            UPCPackSize = Convert.ToInt32(sitequery.Element("UPCPackSize").Value),
            UPC_Code = sitequery.Element("UPC_Code").Value,
            crvId = sitequery.Element("crvId").Value,
            dept = Convert.ToInt32(sitequery.Element("dept").Value),
            description = sitequery.Element("description").Value,
            openQty = Convert.ToDouble(sitequery.Element("openQty").Value),
            packSize = Convert.ToInt32(sitequery.Element("packSize").Value),
            subDept = Convert.ToInt32(sitequery.Element("subDept").Value),
            unitCost = Convert.ToDecimal(sitequery.Element("unitCost").Value),
            unitList = Convert.ToDecimal(sitequery.Element("unitList").Value),
            vendorId = sitequery.Element("vendorId").Value,
            vendorItem = sitequery.Element("vendorItem").Value,
        };
    }