Обходной путь VB .Net NullReferenceException
Это должно быть просто, но у меня проблемы. Используя библиотеку eBay .Net, иногда определенные поля в ответе Nothing
и иногда содержат значение. Когда они Nothing
их можно просто представить в виде пустой строки, но разработчики решили вернуть их как Nothing
поэтому, когда я пытаюсь установить значение String в значение (когда ничего нет), я получаю исключение NullReferenceException, см. ниже
Imports System
Imports System.Configuration.ConfigurationManager
Imports System.Globalization
Imports System.Threading
Imports System.Xml
Imports eBay.Service.Core.Soap
Imports eBay.Service.Core.Sdk
Imports eBay.Service.Call
Imports eBay.Service.Util
Public Class eBayOrderImportService
Private Sub ServiceWorkerThread(ByVal state As Object)
' Periodically check if the service is stopping.
Do While Not Me.stopping
' Perform main service function here...
GetLastTime()
Dim apiContext As ApiContext = GetApiContext()
Dim apiCall As GetOrdersCall = New GetOrdersCall(apiContext)
Dim orders As New OrderTypeCollection
Dim timeFilter As New TimeFilter
timeFilter.TimeFrom = lastUpdate
timeFilter.TimeTo = Date.Now
Dim lastTime As Boolean = SetLastTime()
apiCall.IncludeFinalValueFee = True
orders = apiCall.GetOrders(timeFilter, TradingRoleCodeType.Seller, OrderStatusCodeType.Completed)
Dim order As OrderType
For Each order In orders
'do order-wide stuff here
LogOrder(order)
Next
Thread.Sleep(30 * 1000) ' Simulate some lengthy operations.
Loop
' Signal the stopped event.
Me.stoppedEvent.Set()
End Sub
Private Sub LogOrder(ByVal Order As OrderType)
Dim OrderID, AccountID, BillingFirstName, BillingLastName, _
BillingCompany, BillingEmailAddress, BillingPhone, _
BillingAddress1, BillingAddress2, BillingCity, _
BillingStateProvidence, BillingPostalCode, _
BillingCountry, ShippingFirstName, ShippingLastName, _
ShippingCompany, ShippingEmailAddress, ShippingPhone, _
ShippingAddress1, ShippingAddress2, ShippingCity, _
ShippingStateProvidence, ShippingPostalCode, _
ShippingCountry, OrderStatus, BillingStatus, _
OrderDate, ShippingMethod, SalesTax, _
PreShippingCharge, OrderDiscount, OrderTotalCharged, _
PaymentMethod, RepeatOrder, GiftCode, CouponCode, RID, _
OrderNotes, OrderChannel, IsPrinted, IsShipped, PrintDate, _
ShipDate, ActualShipCharge, DaysInTransit, DeliveryDate, _
TrackingNumber, ShippedMethod As String
OrderID = Order.OrderID
AccountID = ""
Dim name As String = If(Order.ShippingAddress.Name.ToString(), "None Given")
BillingFirstName = name.Substring(0, name.IndexOf(" "))
BillingLastName = name.Substring(name.IndexOf(" ") + 1)
BillingCompany = If(Order.ShippingAddress.CompanyName.ToString(), "")
BillingEmailAddress = If(Order.TransactionArray(0).Buyer.Email.ToString(), "")
BillingPhone = If(Order.ShippingAddress.Phone.ToString(), "")
BillingAddress1 = If(Order.ShippingAddress.Street1.ToString(), "")
BillingAddress2 = If(Order.ShippingAddress.Street2.ToString(), "")
BillingCity = If(Order.ShippingAddress.CityName.ToString(), "")
BillingStateProvidence = If(Order.ShippingAddress.StateOrProvince.ToString(), "")
BillingPostalCode = If(Order.ShippingAddress.PostalCode.ToString(), "")
BillingCountry = If(Order.ShippingAddress.CountryName.ToString(), "")
ShippingFirstName = If(BillingFirstName, "")
ShippingLastName = If(BillingLastName, "")
ShippingCompany = If(Order.ShippingAddress.CompanyName.ToString(), "")
ShippingEmailAddress = If(Order.TransactionArray(0).Buyer.Email.ToString(), "")
ShippingPhone = If(Order.ShippingAddress.Phone.ToString(), "")
ShippingAddress1 = If(Order.ShippingAddress.Street1.ToString(), "")
ShippingAddress2 = If(Order.ShippingAddress.Street2.ToString(), "")
ShippingCity = If(Order.ShippingAddress.CityName.ToString(), "")
ShippingStateProvidence = If(Order.ShippingAddress.StateOrProvince.ToString(), "")
ShippingPostalCode = If(Order.ShippingAddress.PostalCode.ToString(), "")
ShippingCountry = If(Order.ShippingAddress.CountryName.ToString(), "")
OrderStatus = If(Order.OrderStatus.ToString(), "")
BillingStatus = If(Order.OrderStatus.ToString(), "")
OrderDate = If(Order.CreatedTime.ToString("MM/DD/yyyy"), "")
If Order.TransactionArray(0).Taxes IsNot Nothing Then
Dim tmpTax As Double = 0.0
Dim tmpTrans As TransactionType
For Each tmpTrans In Order.TransactionArray
tmpTax = tmpTax + tmpTrans.Taxes.TotalTaxAmount.Value
Next
SalesTax = tmpTax.ToString()
Else
SalesTax = "0.0"
End If
ShippingMethod = If(Order.ShippingServiceSelected.ShippingService.ToString(), "")
ShippingMethod = ShippingMethod & ":" & If(Order.ShippingServiceSelected.ShippingServicePriority.ToString(), "")
OrderTotalCharged = If(Order.Total.Value.ToString(), "")
OrderChannel = "eBay"
comm = New OdbcCommand
comm.CommandText = _
"INSERT INTO Orders (OrderID, AccountID, BillingFirstName, BillingLastName, " & _
"BillingCompany, BillingEmailAddress, BillingPhone, BillingAddress1, " & _
"BillingAddress2, BillingCity, BillingStateProvidence, BillingPostalCode, " & _
"BillingCountry, ShippingFirstName, ShippingLastName, ShippingCompany, " & _
"ShippingEmailAddress, ShippingPhone, ShippingAddress1, ShippingAddress2, " & _
"ShippingCity, ShippingStateProvidence, ShippingPostalCode, ShippingCountry, " & _
"OrderStatus, BillingStatus, OrderDate, SalesTax, ShippingMethod, OrderTotalCharged, OrderChannel) " & _
"VALUES('" & OrderID & "', '" & AccountID & "', '" & BillingFirstName & "', '" & _
BillingLastName & "', '" & BillingCompany & "', '" & BillingEmailAddress & "', '" & _
BillingPhone & "', '" & BillingAddress1 & "', '" & BillingAddress2 & "', '" & BillingCity & "', '" & _
BillingStateProvidence & "', '" & BillingPostalCode & "', '" & BillingCountry & "', '" & _
ShippingFirstName & "', '" & ShippingLastName & "', '" & ShippingCompany & "', '" & _
ShippingEmailAddress & "', '" & ShippingPhone & "', '" & ShippingAddress1 & "', '" & _
ShippingAddress2 & "', '" & ShippingCity & "', '" & ShippingStateProvidence & "', '" & _
ShippingPostalCode & "', '" & ShippingCountry & "', '" & OrderStatus & "', '" & _
BillingStatus & "', '" & OrderDate & "', '" & SalesTax & "', '" & ShippingMethod & "', '" & _
OrderTotalCharged & "', '" & OrderChannel & "')"
' Dim orderResult As Integer = comm.ExecuteNonQuery()
sysLog.WriteEntry(comm.CommandText)
End Sub
End Class
Обновлен код, обратите внимание, что исключение не генерируется до тех пор, пока не будет выполнено:
BillingCompany = If(Order.ShippingAddress.CompanyName.ToString(), ""). Name
свойство имеет значение, которое успешно сохраняется в его переменной, в то время как Order.ShippingAddress.CompanyName
установлен в Nothing
(это свойство существует, и иногда может иметь значение). Я обновил код, чтобы включить ответ Энтони Пеграма, который не помог.
Все объявлено правильно, для сокращения кода я только что показал соответствующий пример. Учтите это внутри цикла для каждого заказа, возвращаемого из вызова GetOrders(), иногда Order.ShippingAddress.CompanyName
ничего не будет, в такие моменты можно ли обрабатывать это как пустую строку? Я попробовал метод ToString (). На других языках я мог бы $CompanyName = this || тот;
Что-нибудь похожее в VB .Net?
3 ответа
Ты можешь использовать If(a, b)
объединить нуль в другое значение. Пример:
Dim obj as String = Nothing
Dim foo as String = If(obj, "foo")
Выводом foo в этом примере будет строка "foo". Если у вас есть ненулевая строка, назначенная для obj, то foo также будет ссылаться на эту строку.
Тем не менее, у меня есть сильное чувство, что ваше исключение нулевой ссылки может происходить не на свойстве, а на объекте. Order
или же ShippingAddress
может быть нулевым. Доступ к свойствам или методам по нулевой ссылке является ошибкой. Простой доступ к нулевому значению путем сохранения его в переменной не является само по себе ошибкой.
Если вы получаете свое исключение на одной из этих строк
CompanyName = Order.ShippingAddress.CompanyName
State = Order.ShippingAddress.StateOrProvince
Это потому, что либо Order или ShippingAddress имеет значение null.
Проверьте и посмотрите, могут ли эти объекты действительно возвращаться как ничего. Если это так, вам нужно применить проверку на нуль вокруг них, прежде чем получить доступ к их свойствам.
Ваше обновление:
Обновлен код, обратите внимание, что исключение не выдается, пока:
BillingCompany = If(Order.ShippingAddress.CompanyName.ToString(), "")
выполнен.
Это может привести к тому, что Order может быть нулевым, ShippingAddress может быть нулевым или CompanyName может быть нулевым. Это исключение для доступа к свойству или методу по нулевой ссылке. Если Order имеет значение null, вы получите ошибку при доступе к ShippingAddress. Аналогично, если ShippingAddress имеет значение null, вы не можете получить доступ к CompanyName. Если CompanyName имеет значение null, вы не можете вызвать ToString().
Вы должны в какой-то момент проверить, какой объект является нулевым. Я не уверен, что ни один из них не будет нулевым. Вы? ПроверьтеПройдите по вашей программе и наблюдайте за состоянием объекта.
Если он сводится к свойствам, таким как CompanyName, равным нулю, и если CompanyName является строкой, пропустите вызов ToString().
BillingCompany = If(Order.ShippingAddress.CompanyName, "")
Если CompanyName не является строкой, вам просто нужно сравнить ее с Nothing перед вызовом ToString () или доступом к свойству.
Посмотрите на эту строку:
CompanyName = Order.ShippingAddress.CompanyName
Если CompanyName
недвижимость в Order.ShippingAddress.CompanyName
является Nothing
, этот код все еще совершенно легален и не вызовет исключение NullReferenceException. Исключение вызвано тем, что либо Order.ShippingAddress
или же Order
само по себе ничто. Вы получаете исключение, потому что вы пытаетесь найти определенное свойство для объекта, который не существует. На основе вашего примера кода легко понять, почему это может быть так:
Dim Order As OrderType
Эта строка объявляет переменную, но фактически никогда не дает этой переменной значение. Order
переменная ссылки на объект... которая еще не установлена для экземпляра объекта. Теперь звучит так, как будто вы пропускаете код, в котором установлен экземпляр, но стоит упомянуть, потому что если это так, то это очень основная часть того, как этот код должен работать, и имеет смысл включить хотя бы заглушку для этого в пример.