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.
July 8, 2008 at 6:56 am
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
July 25, 2008 at 7:18 pm
do you have code to do the address validation through UPS?
Thanks
Rick Rosenhagen
August 6, 2008 at 4:55 pm
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?
August 13, 2008 at 1:50 pm
I’m a little new to ling, can show the code where your defining Linq.ShippingMethod
thanks
September 4, 2008 at 8:12 pm
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();
}
October 20, 2008 at 9:28 pm
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