Обходной путь 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 переменная ссылки на объект... которая еще не установлена ​​для экземпляра объекта. Теперь звучит так, как будто вы пропускаете код, в котором установлен экземпляр, но стоит упомянуть, потому что если это так, то это очень основная часть того, как этот код должен работать, и имеет смысл включить хотя бы заглушку для этого в пример.

TextBox6.Text = Если (xx.GetSumOfPaids(stuid), 0

Другие вопросы по тегам