这应该很简单,但我遇到了问题。使用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中有类似的内容吗?
答案 0 :(得分:11)
您可以使用If(a, b)
将null合并到另一个值。示例:
Dim obj as String = Nothing
Dim foo as String = If(obj, "foo")
此示例中foo的输出将是字符串“foo”。如果你有一个非空字符串分配给obj,那么foo也会引用该字符串。
但是,我有一种强烈的感觉,你的null引用异常可能不会发生在属性上,而是发生在对象上。 Order
或ShippingAddress
可以为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.ShippingAddress
或Order
本身都是Nothing。您得到异常是因为您试图在不存在的对象上查找特定属性。根据您的代码示例,很容易理解为什么会出现这种情况:
Dim Order As OrderType
该行声明了一个变量,但它实际上从未给该变量一个值。 Order
是一个对象引用变量...尚未设置为对象的实例。现在听起来你可能省略了设置实例的代码,但是值得一提,因为如果是这样的话,这是该代码应该如何工作的一个非常基本的部分,并且至少包含一个存根是有意义的样本。