Сужение там, где происходит ошибка выражения LINQ - PullRequest
0 голосов
/ 31 мая 2018

У меня есть большое количество записей (около 2000), возвращенных в виде XML, и я использую оператор LINQ для анализа XML и возврата объектов коллекции.Я, однако, получаю исключение, когда выражения 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>();

1 Ответ

0 голосов
/ 31 мая 2018

Если вы просто хотите избежать исключения, вы можете использовать нулевые операторы C #, чтобы проверить, является ли значение 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 , который описывает структуру XML.Это может помочь найти место, где нет элемента или атрибута или где существуют нежелательные элементы и атрибуты.Вы можете написать XSD вручную или даже сгенерировать его из классов C # .

...