缩小 LINQ 表达式错误发生的位置

Narrowing down where LINQ expression error is occurring

我有大量记录(大约 2,000 条)return编辑为 XML,我正在使用 LINQ 语句来解析 XML 和 return集合对象。但是,我在 LINQ 表达式求值时遇到异常。

object reference not set to an instance of an object

我知道 LINQ 表达式在某处试图处理 null 或缺失的值。当我处理很多 XML.

时,有没有一种方法可以让异常或堆栈跟踪告诉我这可能发生在 XML 的什么地方?

这是我的 LINQ 查询...

XDocument xml = XDocument.Parse(responseXml);
List<PaymentModel> paymentDetails = xml.Descendants("CustomerPayment")
        .Select(x => new PaymentModel
        {
            PaymentRecordNumber = x.Element("InvoiceId").Value.ToString(),
            PaymentMade = (decimal)x.Element("PaymentMade"),
            PaymentDate = !string.IsNullOrEmpty(x.Element("PaymentDate").Value.ToString()) ? (DateTime)x.Element("PaymentDate") : DateTime.MinValue,
            InvoiceCollection = x.Elements("CustomerInvoices")
                .Where(
                    i => i.Element("InvoiceId").Value.Contains("USA")
                    || i.Element("InvoiceId").Value.Contains("JAPAN")
                    || i.Element("InvoiceId").Value.Contains("UK")
                    || i.Element("InvoiceId").Value.Contains("DENMARK")
                )
                .Select(i => new InvoiceModel()
                {
                    InvoiceNumber = i.Element("InvoiceNumber").Value.ToString(),
                    InvoiceAmount = (decimal)i.Element("AmountPaid")
                }).ToList< InvoiceModel>()
        }).ToList<PaymentModel>();

如果您只是想避免异常,您可以使用 C# 的 null 运算符来检查值是否 null 内联并在需要时分配默认值。

您的代码需要如下所示:

List<PaymentModel> paymentDetails = xml.Descendants("CustomerPayment")
        .Select(x => new PaymentModel
        {
            PaymentRecordNumber = x.Element("InvoiceId")?.Value.ToString() ?? String.Empty,
            PaymentMade = Convert.ToDecimal(x.Element("PaymentMade")?.Value ?? "0"),
            PaymentDate = !string.IsNullOrEmpty(x.Element("PaymentDate")?.Value.ToString() ?? String.Empty) ? Convert.ToDateTime(x.Element("PaymentDate")?.Value): DateTime.MinValue,
            InvoiceCollection = x.Elements("CustomerInvoices")?
                .Where(
                    i => (bool)i.Element("InvoiceId")?.Value.Contains("USA")
                    || (bool)i.Element("InvoiceId")?.Value.Contains("JAPAN")
                    || (bool)i.Element("InvoiceId")?.Value.Contains("UK")
                    || (bool)i.Element("InvoiceId")?.Value.Contains("DENMARK")
                )
                .Select(i => new InvoiceModel()
                {
                    InvoiceNumber = i.Element("InvoiceNumber")?.Value.ToString() ?? String.Empty,
                    InvoiceAmount = Convert.ToDecimal(i.Element("AmountPaid")?.Value ?? "0") 
                }).ToList<InvoiceModel>()
        }).ToList<PaymentModel>();

如果你想在XML中找到错误,你可以拆分文件以缩小导致异常的部分或逐行注释掉查询以至少找到元素的名称。

另一种方法是通过使用 XSD, which describes the XML's structure. It can help to find the location where no element or attribute exists or where unwanted elements and attributes exist. You can write the XSD by hand or even generate it from C# classes.

验证文档来检查文档是否有效