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

10 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.

  5. Selva Says:

    Hi,

    Could you please any one send me the code of “HOW TO INTEGRATE UPS SHIPPING RATE into my SITE USING ASP, ACCESS DATABASE”.

    Your reply is highly appreciated.

    Regards
    Selva

  6. Rick Says:

    do you have code to do the address validation through UPS?

    Thanks
    Rick Rosenhagen

  7. Smithveg Says:

    I’m using UPS xml to calculate the shipping cost for United State, from Virginia 24112, and Ground UPS Shipping.

    In my testing, i try to input the Hawaii zipcode. It show me the shipping charges in the result page, in fact, Ground UPS should not allow to send item from Virginia to Hawaii. Any ideas what is happening to UPS XML?

  8. John Says:

    I’m a little new to ling, can show the code where your defining Linq.ShippingMethod

    thanks

  9. Lindall Says:

    This is good I will give it a try if I can’t resolve
    the rate.wsdl That I am using that returns an error message of “System.Web.Services.Protocols.SoapException: An exception has been raised as a result of client data. at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at RateWSs.RateService.ProcessRate(RateRequest RateRequest)”
    the following is my code could you critic it.

    Thank YOu
    protected void wsdlRate()
    {
    // ……………….Rate
    // shipment: To From Shipper Service Pkge serviceOpt RatingOpt pickupType CustomerClass docOnly

    RateWSs.RateService rateSrv = new RateService();
    RateWSs.RateRequest rateReq = new RateRequest();
    RateWSs.UPSSecurity rateSecurity = new RateWSs.UPSSecurity();
    RateWSs.UPSSecurityServiceAccessToken rateToken = new RateWSs.UPSSecurityServiceAccessToken();
    rateToken.AccessLicenseNumber = “EC2E1C5E4DE23E76″; // “5C297F2C8EC005BC”; //EC2E1C5E4DE23E76
    // 5C297F2C8EC005BC 4C2965A228334480
    rateSecurity.ServiceAccessToken = rateToken;
    RateWSs.UPSSecurityUsernameToken usrToken = new RateWSs.UPSSecurityUsernameToken();
    usrToken.Username = “MONGFORD”;
    usrToken.Password = “wprups”;
    rateSecurity.UsernameToken = usrToken;
    rateSrv.UPSSecurityValue = rateSecurity;

    RateWSs.RequestType request = new RateWSs.RequestType();

    String[] requestOpt = { “Rate” }; // here *** //rate or shop

    request.RequestOption = requestOpt;
    // request.TransactionReference = new RateWSs.TransactionReferenceType();
    // request.TransactionReference.CustomerContext = “reqID customer name “;

    rateReq.Request = request;

    // rateReq.Request; rateReq.PickupType; rateReq.Shipment; rateReq.CustomerClassification(opt)

    // rateReq.PickupType = new RateWSs.CodeDescriptionType();
    // rateReq.PickupType.Code = “03″; //one time pickup
    // rateReq.CustomerClassification = new RateWSs.CodeDescriptionType();
    // rateReq.CustomerClassification.Code = “04″; // 04retail 01wholesale

    RateWSs.ShipmentType shipmt = new RateWSs.ShipmentType();

    //rateReq.Shipment = shipmt;
    string[] addrSt = { “16767 Heyden” };
    string[] addrSt2 = new string[1]; addrSt2[0] = “1700 Fairland Drive”;

    RateWSs.ShipFromType shipFrm = new RateWSs.ShipFromType();

    shipFrm.Address = new RateWSs.AddressType();
    shipFrm.Address.AddressLine = addrSt; // here ***
    shipFrm.Address.City = “Detroit”;
    shipFrm.Address.CountryCode = “US”;
    shipFrm.Address.PostalCode = “48219″;
    shipFrm.Address.StateProvinceCode = “MI”;

    shipmt.ShipFrom = shipFrm;

    shipmt.ShipTo = new RateWSs.ShipToType();
    shipmt.ShipTo.Address = new RateWSs.ShipToAddressType();
    shipmt.ShipTo.Address.AddressLine = addrSt;
    shipmt.ShipTo.Address.City = “Detroit”;
    shipmt.ShipTo.Address.CountryCode = “US”;
    shipmt.ShipTo.Address.PostalCode = “48219″;
    shipmt.ShipTo.Address.StateProvinceCode = “MI”;

    // shipmt.Shipper = shipmt.ShipTo;
    shipmt.Shipper = new RateWSs.ShipperType();
    shipmt.Shipper.Address = new RateWSs.AddressType();

    //shipmt.Shipper.Address.AddressLine = new string[2];
    // shipmt.Shipper.Address.AddressLine[0] = “”;
    // shipmt.Shipper.Address.AddressLine[1] = “”;
    shipmt.Shipper.Address.AddressLine = addrSt2;
    shipmt.Shipper.Address.City = “Allen Park”;
    shipmt.Shipper.Address.CountryCode = “US”;
    shipmt.Shipper.Address.PostalCode = “48101″;
    shipmt.Shipper.Address.StateProvinceCode = “MI”;

    shipmt.Service = new RateWSs.CodeDescriptionType();
    shipmt.Service.Code = “03″; // Ground; 14 or 01:next dayAir tbd
    shipmt.Service.Description = “Ground “; // tbd or next day air
    //shipmtDocumentsOnlyIndicator = “true”; shipment include only doucments

    RateWSs.PackageType[] pkgTyp = new RateWSs.PackageType[1]; //tbd loop
    pkgTyp[0] = new RateWSs.PackageType();
    pkgTyp[0].PackagingType = new RateWSs.CodeDescriptionType();
    pkgTyp[0].PackagingType.Code = “04″; //letter tbd 01Letter, 02CustPkg, 03Tube, 04PAC, 21UPSexpressBox,
    pkgTyp[0].Dimensions = new RateWSs.DimensionsType();
    pkgTyp[0].Dimensions.UnitOfMeasurement = new RateWSs.CodeDescriptionType();
    pkgTyp[0].Dimensions.UnitOfMeasurement.Code = “IN”; // CM
    pkgTyp[0].Dimensions.Height = “36″; //tbd
    pkgTyp[0].Dimensions.Width = “48″;
    pkgTyp[0].Dimensions.Length = “36″;

    RateWSs.PackageWeightType pkgWt = new RateWSs.PackageWeightType(); //tbd package weight
    pkgWt.UnitOfMeasurement = new RateWSs.CodeDescriptionType();
    pkgWt.UnitOfMeasurement.Code = “LBS”; // KGS

    pkgTyp[0].PackageWeight = pkgWt;

    //RateWSs.ShipmentServiceOptionsType servOpt = new RateWSs.ShipmentServiceOptionsType()
    //servOpt.COD shipmt.ShipmentServiceOptions = serOpt;
    // shipmt.ShipmentRatingOptions
    // rateReq.PickupType //codedescriptiontype
    // rateReq.CustomerClassification //codedesctype
    shipmt.Package = pkgTyp; // here ***

    // RateWSs.ShipmentRatingOptionsType ratingOpt = new RateWSs.ShipmentRatingOptionsType();
    // ratingOpt.NegotiatedRatesIndicator = upsAcct;

    // ———————————————————
    // shipmt.ShipmentRatingOptions = ratingOpt;
    rateReq.Shipment = shipmt; // mong added here.

    try
    {
    RateWSs.RateResponse rateResp = rateSrv.ProcessRate(rateReq,sss );

    // HttpUtility.HtmlEncode(rateResp).Replace(”<”, “<”).Replace(”</”, “</”);
    //ConfigurationManager.AppSettings["AccessLicenseNumber"],

    rateResp.Response.ResponseStatus.ToString();
    lblTest.Text = “”;
    lblTest.Text = rateResp.Response.ResponseStatus.Code.ToString() + rateResp.Response.ResponseStatus.Description.ToString() + “Lindell5″;

    }
    catch (Exception ex)
    {
    //Response.Write(ex.ToString());
    //Response.Write(ex.Message);
    if (lblTest.Text == “”) { lblTest.Text = “!!! response did not take !!!” + ex.ToString() + ” Lindell6″; }
    }

    // RateService rateService = new App1.RateReference.RateService();

    }

  10. rick lunt Says:

    This is the best I seen. Thanks.

    Having some declaration issue I hope you could help me with.

    VS 2008, ‘DataContext’ and ‘Of Linq.ShippingMethod’

    The ‘Of Linq.ShippingMethod’ refers to the definition within the function which I have never seen but the compiler does not like it.

    Thanks for this an any help you can offer

Leave a Reply