VB .Net NullReferenceException解决方法

时间:2012-02-12 03:29:09

标签: .net vb.net string nullreferenceexception

这应该很简单,但我遇到了问题。使用eBay .Net库,有时响应中的某些字段为Nothing,有时包含值。当它们是Nothing时,它们可以简单地表示为空字符串,但是开发人员选择将它们作为Nothing返回,所以当我尝试将字符串设置为值时(什么也没有)我得到一个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(此属性确实存在,并且有时可以具有值)。我更新了代码,包括Anthony Pegram的答案,但没有帮助。

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

VB .Net中有类似的内容吗?

2 个答案:

答案 0 :(得分:11)

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

Dim obj as String = Nothing
Dim foo as String = If(obj, "foo")

此示例中foo的输出将是字符串“foo”。如果你有一个非空字符串分配给obj,那么foo也会引用该字符串。

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

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

CompanyName = Order.ShippingAddress.CompanyName 
State = Order.ShippingAddress.StateOrProvince

这是因为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, "")

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

答案 1 :(得分:2)

看看这一行:

CompanyName = Order.ShippingAddress.CompanyName

如果CompanyName中的Order.ShippingAddress.CompanyName属性为Nothing,则该代码仍然完全合法,并且会触发NullReferenceException。触发异常是因为Order.ShippingAddressOrder本身都是Nothing。您得到异常是因为您试图在不存在的对象上查找特定属性。根据您的代码示例,很容易理解为什么会出现这种情况:

Dim Order As OrderType

该行声明了一个变量,但它实际上从未给该变量一个Order是一个对象引用变量...尚未设置为对象的实例。现在听起来你可能省略了设置实例的代码,但是值得一提,因为如果是这样的话,这是该代码应该如何工作的一个非常基本的部分,并且至少包含一个存根是有意义的样本。