Kevin Lewis Blog
All about CODE - VB.net, ASP.net, SQL Server, and everything in between

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

4 Responses to “LINQ to UPS to Calculate Shipping Rates”

  1. Matt Says:

    That is nice… Thanks for posting!

  2. Ajay Bhardwaj Says:

    How to inform UPS in case of more then one package of same weight.

  3. Kevin Says:

    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.

  4. Brian Says:

    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.

Leave a Reply