LINQ to UPS to Calculate Shipping Rates
May 22, 2008 Posted by Kevin Lewis
I decided to cleanup my old UPS Webservice Rate Calculation code, and implement some XML literals as well as Linq to XML. The below code is much easier to understand and maintain. I love the new xml syntax for accessing elements.
Private Function GetShippingMethodsFromWeb(ByVal ZipTo As String, ByVal Weight As Integer) As List(Of Linq.ShippingMethod)
Const URL As String = "https://www.ups.com/ups.app/xml/Rate"
If Weight < 1 Then Weight = 1
Dim XMLAuth = <?xml version="1.0"?>
<AccessRequest xml:lang="en-US">
<AccessLicenseNumber><%= App.Settings.UPSAccessKey %></AccessLicenseNumber>
<UserId><%= App.Settings.UPSUserID %></UserId>
<Password><%= App.Settings.UPSPassword %></Password>
</AccessRequest>
Dim XMLRequest = <?xml version="1.0"?>
<RatingServiceSelectionRequest xml:lang="en-US">
<Request>
<TransactionReference>
<CustomerContext>Rating and Service</CustomerContext>
<XpciVersion>1.0001</XpciVersion>
</TransactionReference>
<RequestAction>Rate</RequestAction>
<RequestOption>shop</RequestOption>
</Request>
<PickupType>
<Code>01</Code>
</PickupType>
<Shipment>
<Shipper>
<Address>
<PostalCode><%= App.Settings.ShipFromZipCode %></PostalCode>
</Address>
</Shipper>
<ShipTo>
<Address>
<PostalCode><%= ZipTo %></PostalCode>
<ResidentialAddressIndicator>0</ResidentialAddressIndicator>
<CountryCode>US</CountryCode>
</Address>
</ShipTo>
<Package>
<PackagingType>
<Code>02</Code>
<Description>Package</Description>
</PackagingType>
<Description>Rate Shopping</Description>
<PackageWeight>
<Weight><%= Weight %></Weight>
</PackageWeight>
</Package>
</Shipment>
</RatingServiceSelectionRequest>
'<% If Length > 0 And Width > 0 And Depth > 0 Then %>
' <Dimensions>
' If Length Then
' sXML &= "<Length>" & Length </Length>"
' End If
' If Width Then
' sXML &= "<Width>" & Width </Width>"
' End If
' If Depth Then
' sXML &= "<Height>" & Depth </Height>"
' End If
' sXML &= "</Dimensions>"
'End If
Dim objRequest = System.Net.WebRequest.Create(URL)
objRequest.Method = "POST"
objRequest.ContentType = "application/x-www-form-urlencoded"
Using myWriter = New System.IO.StreamWriter(objRequest.GetRequestStream())
myWriter.Write(XMLAuth.Declaration)
myWriter.Write(XMLAuth)
myWriter.Write(XMLRequest.Declaration)
myWriter.Write(XMLRequest)
myWriter.Flush()
myWriter.Close()
End Using
objRequest.Timeout = 5000
Dim xmlResponse As System.Xml.Linq.XDocument
Using objResponse = objRequest.GetResponse
Using sr As New System.IO.StreamReader(objResponse.GetResponseStream())
xmlResponse = System.Xml.Linq.XDocument.Load(sr)
End Using
End Using
If xmlResponse...<ResponseStatusCode>.Value = "1" Then
Dim Rates = From r In xmlResponse...<RatedShipment> _
Select Code = r...<Code>.Value, _
Charge = CDec(r...<MonetaryValue>.Value)
Dim db As New DataContext
Dim ShippingMethods = (From s In db.ShippingMethods _
Where s.Active AndAlso s.Carrier = "UPS" _
Order By s.SortOrder).ToList
For Each s In ShippingMethods
Dim r = Rates.SingleOrDefault(Function(a) a.Code = s.Code)
If r IsNot Nothing Then
s.ShippingCharge = r.Charge
End If
Next
ShippingMethods.RemoveAll(Function(a) a.ShippingCharge = 0)
Return ShippingMethods
Else
Throw New Exception("An error occurred while calculating UPS shipping rates: " & xmlResponse...<ErrorDescription>.Value & ". Location: " & xmlResponse...<ErrorLocationElementName>.Value)
End If
End Function


May 22, 2008 at 4:51 pm
That is nice… Thanks for posting!
June 5, 2008 at 10:54 am
How to inform UPS in case of more then one package of same weight.
June 5, 2008 at 1:51 pm
Ajay, This service is simply used to calculate the rates (or price) for shipping that particular package. So there is no need to inform UPS of more than one package. You can simply multiply your first result by 2 to get the cost for both packages.
June 27, 2008 at 4:00 pm
Hi Kevin, I can almost understand this. Thank you!
What I now would like to know is how to generate UPS shipping labels using ASP.NET.