简体   繁体   English

在c#控制台应用程序中使用WCF Royal Mail API

[英]Consume WCF Royal Mail API in c# Console Application

I am trying to consume Royal Mail shipping API in my C# Console Application but I am stuck. 我试图在我的C#控制台应用程序中使用皇家邮件运输API,但我被卡住了。 When I make a call to the API, it says Invalid Request.. 当我调用API时,它会显示无效请求..

This is what I did so far 这就是我到目前为止所做的

RoyalMailMessage.cs RoyalMailMessage.cs

 class RoyalMailMessage : Message
    {
        private readonly Message message;

        public RoyalMailMessage(Message message)
        {
            this.message = message;
        }
        public override MessageHeaders Headers
        {
            get
            {
                return this.message.Headers;
            }
        }
        public override MessageProperties Properties
        {
            get
            {
                return this.message.Properties;
            }
        }
        public override MessageVersion Version
        {
            get
            {
                return this.message.Version;
            }
        }
        protected override void OnWriteStartBody(XmlDictionaryWriter writer)
        {
            writer.WriteStartElement("Body", "http://schemas.xmlsoap.org/soap/envelope/");
        }
        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            this.message.WriteBodyContents(writer);
        }
        protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
        {
            writer.WriteStartElement("s", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/");
            writer.WriteAttributeString("xmlns", "v2", null, "http://www.royalmailgroup.com/api/ship/V2");
            writer.WriteAttributeString("xmlns", "v1", null, "http://www.royalmailgroup.com/integration/core/V1");
            writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
            writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
            writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
        }
    }

RoyalMailMessageFormatter.cs RoyalMailMessageFormatter.cs

public class RoyalMailMessageFormatter : IClientMessageFormatter
    {
        private readonly IClientMessageFormatter formatter;

        public RoyalMailMessageFormatter(IClientMessageFormatter formatter)
        {
            this.formatter = formatter;
        }

        public object DeserializeReply(Message message, object[] parameters)
        {
            return this.formatter.DeserializeReply(message, parameters);
        }

        public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
        {
            var message = this.formatter.SerializeRequest(messageVersion, parameters);
            return new RoyalMailMessage(message);
        }
    }

RoyalMailIEndpointBehavior.cs RoyalMailIEndpointBehavior.cs

 class RoyalMailIEndpointBehavior : IOperationBehavior
    {

        public RoyalMailIEndpointBehavior() { }

        public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
        {
            IClientMessageFormatter currentFormatter = proxy.Formatter;
            proxy.Formatter = new RoyalMailMessageFormatter(currentFormatter);
        }

        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        {

        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {

        }

        public void Validate(OperationDescription operationDescription)
        {

        }

    }

Program.cs Program.cs中

class Program
    {
        static void Main(string[] args)
        {

            try
            {

                using (var shippingService = new shippingAPIPortTypeClient())
                {
                    shippingService.ClientCredentials.UserName.UserName = "xxxx";
                    shippingService.ClientCredentials.UserName.Password = "xxxxx";

                    foreach (OperationDescription od in shippingService.Endpoint.Contract.Operations)
                    {
                        od.Behaviors.Add(new RoyalMailIEndpointBehavior());
                    }


                    var createShipment = new createShipmentRequest()
                    {
                        integrationHeader = new integrationHeader()
                        {
                            dateTime = DateTime.Now,
                            dateTimeSpecified = true,
                            debugFlag = false,
                            debugFlagSpecified = false,
                            identification = new identificationStructure()
                            {
                                applicationId = "xxxx",
                                endUserId = "Sandra",
                                intermediaryId = "null",
                                transactionId = "123456789"
                            },
                            performanceFlag = false,
                            performanceFlagSpecified = false,
                            testFlag = false,
                            testFlagSpecified = false,
                            version = 1,
                            versionSpecified = false


                        },
                        requestedShipment = new requestedShipment()
                        {
                            bfpoFormat = new bFPOFormatType()
                            {
                                bFPOFormatCode = null,
                            },
                            customerReference = "",
                            departmentReference = "",

                        }
                    };

                    shippingService.createShipment(null, createShipment);
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

App.Config App.Config中

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="shippingAPISoapBinding">
          <security mode="Transport">
            <transport clientCredentialType="Certificate"></transport>
          </security>
        </binding>

      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://api.royalmail.com/shipping/onboarding" binding="basicHttpBinding"
          bindingConfiguration="shippingAPISoapBinding" contract="ShippingService.shippingAPIPortType"
          name="shippingAPIPort" behaviorConfiguration="CustomBehavior" />
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="CustomBehavior">
          <clientCredentials>
            <clientCertificate findValue="RM10001815" x509FindType="FindBySubjectName"
              storeLocation="CurrentUser" storeName="My" />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

  </system.serviceModel>
</configuration>

Now, when I make a call to the API, it says "Invalid Request"..I am not sure if I missing anything, may be adding credentials in Soap Envelop header like below? 现在,当我调用API时,它会显示“无效请求”..我不确定我是否遗漏了任何内容,可能会在Soap Envelop标题中添加凭据,如下所示?

<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>xxxx</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">xxxx</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">xWstjXG0iUxbv3NH/fX+kw==</wsse:Nonce>
<wsu:Created>2014-08-16T15:29:42</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>

Firstly you are missing the security header as you have already identified, plus a whole host of other fields in your createShipment request such as address, service code etc. I would strongly suggest using fiddler to capture your SOAP requests and responses, they will give you a lot more insight into what is happening. 首先,您缺少已经识别的安全标头,以及您的createShipment请求中的许多其他字段,例如地址,服务代码等。我强烈建议使用fiddler捕获您的SOAP请求和响应,它们会给您更深入地了解正在发生的事情。 You can also compare the requests you are generating with the example requests provided by royal mail onboarding. 您还可以将您生成的请求与皇家邮件入职提供的示例请求进行比较。

Looking at your code, you are not attaching the security tokens (the wsse) which needs to be unique for every request you make (The nonce token that is). 查看您的代码,您没有附加安全令牌(wsse),它对于您发出的每个请求都必须是唯一的(nonce令牌)。 You are also missing a variety of other required fields for the createShipemt request such as address, service code and type etc. 您还缺少createShipemt请求的各种其他必填字段,例如地址,服务代码和类型等。

I had to attach the certificate and key to the request to make it work as well. 我必须将证书和密钥附加到请求以使其工作。 Below are some fragments of the code I created to make this work, it's not a copy paste solution but better than anything else you will find out there with regards to Royal Mail and C# and should point you in the right direction. 下面是我为使这项工作而创建的代码的一些片段,它不是一个复制粘贴解决方案,但比你在皇家邮政和C#方面找到的任何其他内容更好,并且应该指向正确的方向。

Please note, I have config class which loads a lot of the settings from an sqlite database (not posted). 请注意,我有一个config类,它从sqlite数据库(未发布)加载了很多设置。 The values for the createShipment request are coming from a form (not posted) which is pre-populated with the data but allows the user in our warehouse to alter and adjust accordingly. createShipment请求的值来自一个表单(未发布),该表单预先填充了数据,但允许我们仓库中的用户进行相应的更改和调整。 You have already made use of my custom message formatter example from post ( C# WCF (Royal Mail SOAP API) Declare Namespace In Header ) to handle the namespace issue. 您已经使用post中的自定义消息格式化程序示例( C#WCF(皇家邮件SOAP API)声明名称空间在标头中 )来处理名称空间问题。 Royal Mail API is not easy to implement in C#, took me nearly 2 days to get a valid request and response and as I say, you really need to capture the requests and responses to work out what is going on. Royal Mail API在C#中实现起来并不容易,我花了将近2天的时间来获得有效的请求和响应,正如我所说,你真的需要捕获请求和响应来解决发生的事情。

private X509Certificate2 certificate;
private Config config;

    public RoyalMail() {

        // Load The Config
        config = new Config();
        config.loadConfig();

        // Load The SSL Certificate (Check The File Exists)
        String certificatePath = (Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\" + config.GetCertificateName());

        if (!System.IO.File.Exists(certificatePath))
        {
            throw new Exception(@"The Royal Mail Certificate Is Missing From The Plugins Directory. Please Place The File " + config.GetCertificateName() + " In The Same Directory As The Plugin DLL File & Relaunch FileMaker.\n\n" + certificatePath);
        }

        certificate = new X509Certificate2(certificatePath, config.GetCertificatePassword());

        // Check It's In The Certificate 
        X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadWrite);
        if (!store.Certificates.Contains(certificate))
        {
            store.Add(certificate);
            MessageBox.Show("Certificate Was Installed Into Computer Trust Store");
        }
        store.Close(); 

    }


    /*
     * 
     * SOAP Service & Methods
     * 
     */

    private shippingAPIPortTypeClient GetProxy()
    {

        BasicHttpBinding myBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
        myBinding.MaxReceivedMessageSize = 2147483647;
        myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

        shippingClient = new shippingAPIPortTypeClient(myBinding, new EndpointAddress(new Uri(config.GetEndpointURL()), EndpointIdentity.CreateDnsIdentity("api.royalmail.com"), new AddressHeaderCollection()));
        shippingClient.ClientCredentials.ClientCertificate.Certificate = certificate;

        foreach (OperationDescription od in shippingClient.Endpoint.Contract.Operations)
        {
            od.Behaviors.Add(new RoyalMailIEndpointBehavior());
        }
        return shippingClient;
    }


    private SecurityHeaderType GetSecurityHeaderType()
    {
        SecurityHeaderType securityHeader = new SecurityHeaderType();

        DateTime created = DateTime.Now;

        string creationDate;
        creationDate = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");

        string nonce = nonce = (new Random().Next(0, int.MaxValue)).ToString();

        byte[] hashedPassword;
        hashedPassword = GetSHA1(config.GetPassword());

        string concatednatedDigestInput = string.Concat(nonce, creationDate, Encoding.Default.GetString(hashedPassword));
        byte[] digest;
        digest = GetSHA1(concatednatedDigestInput);

        string passwordDigest;
        passwordDigest = Convert.ToBase64String(digest);

        string encodedNonce;
        encodedNonce = Convert.ToBase64String(Encoding.Default.GetBytes(nonce));

        XmlDocument doc = new XmlDocument();
        using (XmlWriter writer = doc.CreateNavigator().AppendChild())
        {
            writer.WriteStartDocument();
            writer.WriteStartElement("Security");
            writer.WriteStartElement("UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            writer.WriteElementString("Username", config.GetUsername());
            writer.WriteElementString("Password", passwordDigest);
            writer.WriteElementString("Nonce", encodedNonce);
            writer.WriteElementString("Created", creationDate);
            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Flush();
        }

        doc.DocumentElement.RemoveAllAttributes();

        System.Xml.XmlElement[] headers = doc.DocumentElement.ChildNodes.Cast<XmlElement>().ToArray<XmlElement>();

        securityHeader.Any = headers;

        return securityHeader;

    }

    private integrationHeader GetIntegrationHeader()
    {
        integrationHeader header = new integrationHeader();

        DateTime created = DateTime.Now;
        String createdAt = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");

        header.dateTime = created;
        header.version = Int32.Parse(config.GetVersion());
        header.dateTimeSpecified = true;
        header.versionSpecified = true;

        identificationStructure idStructure = new identificationStructure();
        idStructure.applicationId = config.GetApplicationID();

        string nonce = nonce = (new Random().Next(0, int.MaxValue)).ToString();

        idStructure.transactionId = CalculateMD5Hash(nonce + createdAt);

        header.identification = idStructure;

        return header;
    }

    private static byte[] GetSHA1(string input)
    {
        return SHA1Managed.Create().ComputeHash(Encoding.Default.GetBytes(input));
    }

    public string CalculateMD5Hash(string input)
    {
        // step 1, calculate MD5 hash from input
        MD5 md5 = System.Security.Cryptography.MD5.Create();
        byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
        byte[] hash = md5.ComputeHash(inputBytes);

        // step 2, convert byte array to hex string
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hash.Length; i++)
        {
            sb.Append(hash[i].ToString("X2"));
        }
        return sb.ToString();
    }



    /*
     * Check Response Footer For Errors & Warnings From Service
     * If Error Return True So We Can Inform Filemaker Of Error
     * Ignore Warnings For Now
     * 
     */
    private bool checkErrorsAndWarnings(integrationFooter integrationFooter)
    {
        if (integrationFooter != null)
        {
            if (integrationFooter.errors != null && integrationFooter.errors.Length > 0)
            {
                errorDetail[] errors = integrationFooter.errors;
                for (int i = 0; i < errors.Length; i++)
                {
                    errorDetail error = errors[i];
                    MessageBox.Show("Royal Mail Request Error: " + error.errorDescription + ". " + error.errorResolution, "Royal Mail Request Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                }
                if (errors.Length > 0)
                {
                    return true;
                }
            }

            if (integrationFooter.warnings != null && integrationFooter.warnings.Length > 0)
            {
                warningDetail[] warnings = integrationFooter.warnings;
                for (int i = 0; i < warnings.Length; i++)
                {
                    warningDetail warning = warnings[i];
                    //MessageBox.Show("Royal Mail Request Warning: " + warning.warningDescription + ". " + warning.warningResolution, "Royal Mail Request Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
                }
            }
        }

        return false;

    }

    /*
     * Show Message Box With SOAP Error If We Receive A Fault Code Back From Service
     *
     */
    private void showSoapException(FaultException e)
    {
        MessageFault message = e.CreateMessageFault();

        XmlElement errorDetail = message.GetDetail<XmlElement>();

        XmlNodeList errorDetails = errorDetail.ChildNodes;

        String fullErrorDetails = "";

        for (int i = 0; i < errorDetails.Count; i++)
        {
            fullErrorDetails += errorDetails.Item(i).Name + ": " + errorDetails.Item(i).InnerText + "\n";
        }

        MessageBox.Show("An Error Occured With Royal Mail Service: " + message.Reason.ToString() + "\n\n" + fullErrorDetails, "Royal Mail SOAP Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
    }

    public createShipmentResponse SendCreateShipmentRequest(CreateShipmentForm shippingForm)
    {

        shippingAPIPortTypeClient client = GetProxy();

        try
        {

            createShipmentRequest request = new createShipmentRequest();
            request.integrationHeader = GetIntegrationHeader();

            requestedShipment shipment = new requestedShipment();

            // Shipment Type Code (Delivery or Return)
            referenceDataType shipmentType = new referenceDataType();
            shipmentType.code = shippingForm.GetShippingType();
            shipment.shipmentType = shipmentType;

            // Service Occurence (Identifies Agreement on Customers Account) Default to 1. Not Required If There Is There Is Only 1 On Account
            shipment.serviceOccurrence = config.GetServiceOccurance();

            // Service Type Code (1:24H 1st Class, 2: 48H 2nd Class, D: Special Delivery Guaranteed, H: HM Forces (BFPO), I: International, R: Tracked Returns, T: Tracked Domestic)
            referenceDataType serviceType = new referenceDataType();
            serviceType.code = shippingForm.GetServiceType().GetServiceTypeCode();
            shipment.serviceType = serviceType;

            // Service Offering (See Royal Mail Service Offering Type Codes. Too Many To List)
            serviceOfferingType serviceOfferingTypeContainer = new serviceOfferingType();
            referenceDataType serviceOffering = new referenceDataType();
            serviceOffering.code = shippingForm.GetServiceOffering().GetCode();
            serviceOfferingTypeContainer.serviceOfferingCode = serviceOffering;
            shipment.serviceOffering = serviceOfferingTypeContainer;

            // Service Format Code
            serviceFormatType serviceFormatTypeContainer = new serviceFormatType();
            referenceDataType serviceFormat = new referenceDataType();
            serviceFormat.code = shippingForm.GetServiceFormat().GetFormat();
            serviceFormatTypeContainer.serviceFormatCode = serviceFormat;
            shipment.serviceFormat = serviceFormatTypeContainer;

            // Shipping Date
            shipment.shippingDate = shippingForm.GetShippingDate();
            shipment.shippingDateSpecified = true;

            // Signature Required (Only Available On Tracked Services)
            if (shippingForm.IsSignatureRequired())
            {
                shipment.signature = true;
            }
            else
            {
                shipment.signature = false;

                // Leave In Safe Place (Available On Tracked Non Signature Service Offerings)
                shipment.safePlace = shippingForm.GetSafePlaceText();
            }
            shipment.signatureSpecified = true;

            // Sender Reference Number (e.g. Invoice Number or RA Number)
            shipment.senderReference = shippingForm.GetInvoiceNumber();

            /*
             * Service Enhancements
            */

            List<serviceEnhancementType> serviceEnhancements = new List<serviceEnhancementType>();

            List<dataObjects.ServiceEnhancement> selectedEnhancements = shippingForm.GetServiceEnhancements();

            for (int i = 0; i < selectedEnhancements.Count; i++)
            {
                serviceEnhancementType enhancement = new serviceEnhancementType();
                referenceDataType enhancementCode = new referenceDataType();
                enhancementCode.code = selectedEnhancements.ElementAt(i).GetEnhancementType().ToString();
                enhancement.serviceEnhancementCode = enhancementCode;
                serviceEnhancements.Add(enhancement);
            }

            shipment.serviceEnhancements = serviceEnhancements.ToArray();


            /*
             * Recipient Contact Details
            */

            contact recipientContact = new contact();
            recipientContact.complementaryName = shippingForm.GetCompany();
            recipientContact.name = shippingForm.GetName();

            if(!shippingForm.GetEmailAddress().Equals("")) {
                digitalAddress email = new digitalAddress();
                email.electronicAddress = shippingForm.GetEmailAddress();
                recipientContact.electronicAddress = email;
            }

            if(!shippingForm.GetMobileNumber().Equals("")) {
                telephoneNumber tel = new telephoneNumber();

                Regex phoneRegex = new Regex(@"[^\d]");
                tel.telephoneNumber1 = phoneRegex.Replace(shippingForm.GetMobileNumber(), "");
                tel.countryCode = "00" + shippingForm.GetCountry().GetDialingCode();
                recipientContact.telephoneNumber = tel;
            }

            shipment.recipientContact = recipientContact;

            /*
             * Recipient Address
             * 
            */
            address recipientAddress = new address();
            recipientAddress.addressLine1 = shippingForm.GetAddressLine1();
            recipientAddress.addressLine2 = shippingForm.GetAddressLine2();
            recipientAddress.addressLine3 = shippingForm.GetAddressLine3();
            recipientAddress.addressLine4 = shippingForm.GetCounty();
            recipientAddress.postTown = shippingForm.GetTown();
            countryType country = new countryType();
            referenceDataType countryCode = new referenceDataType();
            countryCode.code = shippingForm.GetCountry().getCountryCode();
            country.countryCode = countryCode;
            recipientAddress.country = country;
            recipientAddress.postcode = shippingForm.GetPostCode();

            recipientAddress.stateOrProvince = new stateOrProvinceType();
            recipientAddress.stateOrProvince.stateOrProvinceCode = new referenceDataType();

            shipment.recipientAddress = recipientAddress;

            // Shipment Items

            List<RoyalMailAPI.RoyalMailShippingAPI.item> items = new List<RoyalMailAPI.RoyalMailShippingAPI.item> ();

            foreach(dataObjects.Item i in shippingForm.GetItems()) {
                RoyalMailAPI.RoyalMailShippingAPI.item item = new RoyalMailAPI.RoyalMailShippingAPI.item();
                item.numberOfItems = i.GetQty().ToString();
                item.weight = new dimension();
                item.weight.value = (float) (i.GetWeight() * 1000);
                item.weight.unitOfMeasure = new unitOfMeasureType();
                item.weight.unitOfMeasure.unitOfMeasureCode = new referenceDataType();
                item.weight.unitOfMeasure.unitOfMeasureCode.code = "g";

                items.Add(item);
            }

            if (shippingForm.GetServiceType().GetDescription().ToLower().Contains("international"))
            {
                internationalInfo InternationalInfo = new internationalInfo();
                InternationalInfo.shipperExporterVatNo = "GB945777273";
                InternationalInfo.documentsOnly = false;
                InternationalInfo.shipmentDescription = "Invoice Number: " + shippingForm.GetInvoiceNumber();
                InternationalInfo.invoiceDate = DateTime.Now;
                InternationalInfo.termsOfDelivery = "EXW";
                InternationalInfo.invoiceDateSpecified = true;
                InternationalInfo.purchaseOrderRef = shippingForm.GetInvoiceNumber();

                List<RoyalMailShippingAPI.parcel> parcels = new List<parcel>();
                foreach (dataObjects.Item i in shippingForm.GetItems())
                {
                    parcel Parcel = new parcel();
                    Parcel.weight = new dimension();
                    Parcel.weight.value = (float)(i.GetWeight() * 1000);
                    Parcel.weight.unitOfMeasure = new unitOfMeasureType();
                    Parcel.weight.unitOfMeasure.unitOfMeasureCode = new referenceDataType();
                    Parcel.weight.unitOfMeasure.unitOfMeasureCode.code = "g";

                    Parcel.invoiceNumber = shippingForm.GetInvoiceNumber();
                    Parcel.purposeOfShipment = new referenceDataType();
                    Parcel.purposeOfShipment.code = "31";

                    List<contentDetail> Contents = new List<contentDetail>();
                    foreach (RoyalMailAPI.dataObjects.ProductDetail product in i.GetProducts())
                    {
                        contentDetail ContentDetail = new contentDetail();
                        ContentDetail.articleReference = product.Sku;
                        ContentDetail.countryOfManufacture = new countryType();
                        ContentDetail.countryOfManufacture.countryCode = new referenceDataType();
                        ContentDetail.countryOfManufacture.countryCode.code = product.CountryOfManufacture;

                        ContentDetail.currencyCode = new referenceDataType();
                        ContentDetail.currencyCode.code = product.CurrencyCode;
                        ContentDetail.description = product.Name;
                        ContentDetail.unitQuantity = product.Qty.ToString();
                        ContentDetail.unitValue = Convert.ToDecimal(product.Price);
                        ContentDetail.unitWeight = new dimension();
                        ContentDetail.unitWeight.value = Convert.ToSingle(product.Weight * 1000);
                        ContentDetail.unitWeight.unitOfMeasure = new unitOfMeasureType();
                        ContentDetail.unitWeight.unitOfMeasure.unitOfMeasureCode = new referenceDataType();
                        ContentDetail.unitWeight.unitOfMeasure.unitOfMeasureCode.code = "g";


                        Contents.Add(ContentDetail);
                    }

                    //Parcel.contentDetails = Contents.ToArray();

                    parcels.Add(Parcel);

                }

                InternationalInfo.parcels = parcels.ToArray();

                shipment.internationalInfo = InternationalInfo;
            }
            else
            {
                shipment.items = items.ToArray();
            }

            request.requestedShipment = shipment;

            createShipmentResponse response = client.createShipment(GetSecurityHeaderType(), request);

            // Show Errors And Warnings
            checkErrorsAndWarnings(response.integrationFooter);

            return response;

        }
        catch (TimeoutException e)
        {
            client.Abort();
            MessageBox.Show("Request Timed Out: " + e.Message, "Request Timeout", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
        }
        catch (FaultException e)
        {
            client.Abort();
            showSoapException(e);
        }
        catch (CommunicationException e)
        {
            client.Abort();
            MessageBox.Show("A communication error has occured: " + e.Message + " - " + e.StackTrace, "Communication Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
        }
        catch (Exception e)
        {
            client.Abort();
            MessageBox.Show(e.Message, "Royal Mail Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
        }

        return null;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM