VB .Net NullReferenceException解决方法

Mik*_* L. 6 .net vb.net string 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
Run Code Online (Sandbox Code Playgroud)

有更新的代码请注意没有异常被抛出,直到:BillingCompany = If(Order.ShippingAddress.CompanyName.ToString(),"")被执行.该Name属性具有成功存储到其变量中的值,而Order.ShippingAddress.CompanyName设置为Nothing(此属性确实存在,有时可以具有值).我更新了代码,包括Anthony Pegram的答案,但没有帮助.

一切都被正确宣布,缩短我刚刚展示相关示例的代码.对于从GetOrders()调用返回的每个订单,请考虑这个循环内部,有时候Order.ShippingAddress.CompanyName什么都不会,在这些时候是否可以将其作为空字符串处理?我尝试了ToString()方法.在其他语言中我可以$ CompanyName = this || 那;

VB .Net中有类似的东西吗?

Ant*_*ram 11

您可以使用If(a, b)将null合并到另一个值.例:

Dim obj as String = Nothing
Dim foo as String = If(obj, "foo")
Run Code Online (Sandbox Code Playgroud)

在这个例子中,foo的输出将是字符串"foo".如果你有一个非空字符串分配给obj,那么foo也会引用该字符串.

但是,我有一种强烈的感觉,你的null引用异常可能不是在属性上发生,而是在对象上发生.Order或者ShippingAddress可以为null.访问空引用上的属性或方法是一个错误.简单地通过将空值存储到变量来访问空值本身并不是错误.

如果您在其中一行上获得例外

CompanyName = Order.ShippingAddress.CompanyName 
State = Order.ShippingAddress.StateOrProvince
Run Code Online (Sandbox Code Playgroud)

这是因为Order或ShippingAddress为空.

检查并查看这些对象是否实际上无法返回.如果是这样,您将需要在访问其属性之前对它们应用空值检查.


你的更新:

有更新的代码请注意没有例外被抛出,直到:

BillingCompany = If(Order.ShippingAddress.CompanyName.ToString(), "")

被执行.

这可以抛出,因为Order可以为null,ShippingAddress可以为null,或者CompanyName可以为null.访问null引用上的属性或方法是一个例外.如果Order为null,则访问ShippingAddress时将出错.Similarlu,如果ShippingAddress为null,则无法访问CompanyName.如果CompanyName为null,则无法调用ToString().

您必须在某些时候验证哪个对象为空.我不相信他们中的任何一个都不会为空.你呢?检查.逐步完成程序并观察对象状态.

如果它确实归结为CompanyName为null的属性,并且如果CompanyName是字符串,则省略ToString()调用.

BillingCompany = If(Order.ShippingAddress.CompanyName, "")
Run Code Online (Sandbox Code Playgroud)

如果CompanyName 不是字符串,则只需在调用ToString()或访问属性之前将其与Nothing进行比较.