【问题标题】:Need Raw XML For Request & Response In UPS API (.Net)UPS API (.Net) 中的请求和响应需要原始 XML
【发布时间】:2012-07-06 15:57:53
【问题描述】:

这个问题的答案可能非常明显。但是需要一些帮助...

我目前正在使用 UPS API/服务来生成测试标签。一切都很好。但要获得认证,我必须将请求和响应中的原始 XML 发送给 UPS。

我不是发送原始 xml,而是使用服务及其各种属性。发货结果中的某处是否返回了原始 XML?还是必须手动序列化请求和响应以满足 UPS 在审查中的要求?

这是我的代码(一切正常,我能够生成标签。但是如何获取请求和响应 xml?)

try
        {
            ShipService shpSvc = new ShipService();
            ShipmentRequest shipmentRequest = new ShipmentRequest();
            UPSSecurity upss = new UPSSecurity();
            UPSSecurityServiceAccessToken upssSvcAccessToken = new UPSSecurityServiceAccessToken();
            upssSvcAccessToken.AccessLicenseNumber = s.APIKey;
            upss.ServiceAccessToken = upssSvcAccessToken;
            UPSSecurityUsernameToken upssUsrNameToken = new UPSSecurityUsernameToken();
            upssUsrNameToken.Username = s.Username;
            upssUsrNameToken.Password = s.Password;
            upss.UsernameToken = upssUsrNameToken;
            shpSvc.UPSSecurityValue = upss;
            RequestType request = new RequestType();

            String[] requestOption = { "nonvalidate" };
            request.RequestOption = requestOption;
            shipmentRequest.Request = request;                

    ShipmentType shipment = new ShipmentType();                
            ShipperType shipper = new ShipperType();
            shipper.ShipperNumber = s.ShipperAccountNumber;
            PaymentInfoType paymentInfo = new PaymentInfoType();

    ShipmentChargeType shpmentCharge = new ShipmentChargeType();
            BillShipperType billShipper = new BillShipperType();
            billShipper.AccountNumber = s.ShipperAccountNumber;
            shpmentCharge.BillShipper = billShipper;
            shpmentCharge.Type = "01";

    ShipmentChargeType[] shpmentChargeArray = { shpmentCharge };
            paymentInfo.ShipmentCharge = shpmentChargeArray;
            shipment.PaymentInformation = paymentInfo;
            ShipWebReference.ShipAddressType shipperAddress = new ShipWebReference.ShipAddressType();
            String[] addressLine = { s.ShipperAddressLine };

    shipperAddress.AddressLine = addressLine;
            shipperAddress.City = s.ShipperCity;
            shipperAddress.PostalCode = s.ShipperZip;
            shipperAddress.StateProvinceCode = s.ShipperState;
            shipperAddress.CountryCode = "US";
            shipperAddress.AddressLine = addressLine;
            shipper.Address = shipperAddress;
            shipper.Name = s.ShipperName;
            shipper.AttentionName = s.ShipperName;
            ShipPhoneType shipperPhone = new ShipPhoneType();
            shipperPhone.Number = s.ShipperPhone;
            shipper.Phone = shipperPhone;
            shipment.Shipper = shipper;
            ShipFromType shipFrom = new ShipFromType();

    ShipWebReference.ShipAddressType shipFromAddress = new ShipWebReference.ShipAddressType();
            String[] shipFromAddressLine = { s.ShipperAddressLine };
            shipFromAddress.AddressLine = addressLine;
            shipFromAddress.City = s.ShipperCity;
            shipFromAddress.PostalCode = s.ShipperZip;
            shipFromAddress.StateProvinceCode = s.ShipperState;
            shipFromAddress.CountryCode = "US";
            shipFrom.Address = shipFromAddress;
            shipFrom.AttentionName = s.ShipperName;
            shipFrom.Name = s.ShipperName;
            shipment.ShipFrom = shipFrom;

    ShipToType shipTo = new ShipToType();
            ShipToAddressType shipToAddress = new ShipToAddressType();
            String[] addressLine1 = { s.ShipToAddressLine };
            shipToAddress.AddressLine = addressLine1;
            shipToAddress.City = s.ShipToCity;
            shipToAddress.PostalCode = s.ShipToZip;
            shipToAddress.StateProvinceCode = s.ShipToState;
            shipToAddress.CountryCode = "US";
            shipTo.Address = shipToAddress;
            shipTo.AttentionName = s.ShipToName;
            shipTo.Name = s.ShipToName;

            ShipPhoneType shipToPhone = new ShipPhoneType();
            shipToPhone.Number = s.ShipToPhone;
            shipTo.Phone = shipToPhone;
            shipment.ShipTo = shipTo;
            ServiceType service = new ServiceType();

            service.Code = "03";
            shipment.Service = service;
            PackageType package = new PackageType();
            PackageWeightType packageWeight = new PackageWeightType();
            packageWeight.Weight = s.PackageWeight;
            ShipUnitOfMeasurementType uom = new ShipUnitOfMeasurementType();
            uom.Code = "LBS";
            packageWeight.UnitOfMeasurement = uom;
            package.PackageWeight = packageWeight;
            PackagingType packType = new PackagingType();
            packType.Code = "02";
            package.Packaging = packType;
            PackageType[] pkgArray = { package };
            shipment.Package = pkgArray;
            LabelSpecificationType labelSpec = new LabelSpecificationType();
            LabelStockSizeType labelStockSize = new LabelStockSizeType();
            labelStockSize.Height = "6";
            labelStockSize.Width = "4";
            labelSpec.LabelStockSize = labelStockSize;
            LabelImageFormatType labelImageFormat = new LabelImageFormatType();
            LabelDeliveryType labelDel = new LabelDeliveryType();
            labelDel.LabelLinksIndicator = "";
            labelImageFormat.Code = "GIF";

            PackageServiceOptionsType packServiceOptions = new PackageServiceOptionsType();
            PackageDeclaredValueType decType = new PackageDeclaredValueType();
            decType.CurrencyCode = "USD";
            decType.MonetaryValue = s.PackageValue;
            packServiceOptions.DeclaredValue = decType;
            package.PackageServiceOptions = packServiceOptions;


            labelSpec.LabelImageFormat = labelImageFormat;
            ShipmentTypeShipmentServiceOptions shipServOpt = new ShipmentTypeShipmentServiceOptions();

            shipment.ShipmentServiceOptions = shipServOpt;


            shipmentRequest.LabelSpecification = labelSpec;
            shipmentRequest.Shipment = shipment;

            System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
            Console.WriteLine(shipmentRequest);

            shipmentResponse = shpSvc.ProcessShipment(shipmentRequest);               

        }

【问题讨论】:

    标签: .net xml api ups


    【解决方案1】:

    我也遇到了同样的问题,幸运的是我解决了这个问题;)

    您需要一些东西来注册一个 SOAP 扩展:

     [ReflectionPermission(SecurityAction.Demand, Unrestricted = true)]
        public static void RegisterSoapExtension(Type type, int priority, PriorityGroup group)
        {
            if (!type.IsSubclassOf(typeof(SoapExtension)))
            {
                throw new ArgumentException("Type must be derived from SoapException.", "type");
            }
    
            if (priority < 1)
            {
                throw new ArgumentOutOfRangeException("priority", priority, "Priority must be greater or equal to 1.");
            }
    
            // get the current web services settings...  
            WebServicesSection wss = WebServicesSection.Current;
    
            // set SoapExtensionTypes collection to read/write...  
            FieldInfo readOnlyField = typeof(System.Configuration.ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
            readOnlyField.SetValue(wss.SoapExtensionTypes, false);
    
            // inject SoapExtension...  
            //wss.SoapExtensionTypes.Add(new SoapExtensionTypeElement(type, priority, group));
    
            System.Web.Services.Configuration.SoapExtensionTypeElement soapInterceptor = new SoapExtensionTypeElement();
            soapInterceptor.Type = type;
            soapInterceptor.Priority = priority;
            soapInterceptor.Group = group;
            wss.SoapExtensionTypes.Add(soapInterceptor);
    
            // set SoapExtensionTypes collection back to readonly and clear modified flags...  
            MethodInfo resetModifiedMethod = typeof(System.Configuration.ConfigurationElement).GetMethod("ResetModified", BindingFlags.NonPublic | BindingFlags.Instance);
            resetModifiedMethod.Invoke(wss.SoapExtensionTypes, null);
            MethodInfo setReadOnlyMethod = typeof(System.Configuration.ConfigurationElement).GetMethod("SetReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
            setReadOnlyMethod.Invoke(wss.SoapExtensionTypes, null);
        }
    

    您需要定义实际的扩展名:

    /// <summary>
    /// SOAP Extension that traces the SOAP request and
    /// SOAP response to a SOAP API Web service. 
    /// </summary>
    public class TraceExtension : SoapExtension
    {
        private Stream oldStream;
        private Stream newStream;
    
        private static XmlDocument xmlRequest;
    
        /// <summary>
        /// Gets the outgoing XML request
        /// </summary>
        public static XmlDocument XmlRequest
        {
            get { return xmlRequest; }
        }
    
        private static XmlDocument xmlResponse;
    
        /// <summary>
        /// Gets the incoming XML response
        /// </summary>
        public static XmlDocument XmlResponse
        {
            get { return xmlResponse; }
        }
    
        /// <summary>
        /// Save the Stream representing the SOAP request
        /// or SOAP response into a local memory buffer. 
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public override Stream ChainStream(Stream stream)
        {
            oldStream = stream;
            newStream = new MemoryStream();
            return newStream;
        }
    
        /// <summary>
        /// If the SoapMessageStage is such that the SoapRequest or
        /// SoapResponse is still in the SOAP format to be sent or received,
        /// save it to the xmlRequest or xmlResponse property.
        /// </summary>
        /// <param name="message"></param>
        public override void ProcessMessage(SoapMessage message)
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeSerialize:
                    break;
                case SoapMessageStage.AfterSerialize:
                    xmlRequest = GetSoapEnvelope(newStream);
                    CopyStream(newStream, oldStream);
                    break;
                case SoapMessageStage.BeforeDeserialize:
                    CopyStream(oldStream, newStream);
                    xmlResponse = GetSoapEnvelope(newStream);
                    break;
                case SoapMessageStage.AfterDeserialize:
                    break;
            }
        }
    
        /// <summary>
        /// Returns the XML representation of the Soap Envelope in the supplied stream.
        /// Resets the position of stream to zero.
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        private XmlDocument GetSoapEnvelope(Stream stream)
        {
            var xml = new XmlDocument();
            stream.Position = 0;
            var reader = new StreamReader(stream);
            xml.LoadXml(reader.ReadToEnd());
            stream.Position = 0;
            return xml;
        }
    
        /// <summary>
        /// Copies a stream.
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        private void CopyStream(Stream from, Stream to)
        {
            TextReader reader = new StreamReader(from);
            TextWriter writer = new StreamWriter(to);
            writer.WriteLine(reader.ReadToEnd());
            writer.Flush();
        }
    
    
        /// <summary>
        /// Included only because it must be implemented.
        /// </summary>
        /// <param name="methodInfo"></param>
        /// <param name="attribute"></param>
        /// <returns></returns>
        public override object GetInitializer(LogicalMethodInfo methodInfo,
                                              SoapExtensionAttribute attribute)
        {
            return null;
        }
    
        /// <summary>
        /// Included only because it must be implemented.
        /// </summary>
        /// <param name="WebServiceType"></param>
        /// <returns></returns>
        public override object GetInitializer(Type WebServiceType)
        {
            return null;
        }
    
        /// <summary>
        /// Included only because it must be implemented.
        /// </summary>
        /// <param name="initializer"></param>
        public override void Initialize(object initializer)
        {
        }
    
    
    }
    

    然后你需要注册扩展:

    RegisterSoapExtension(typeof(TraceExtension), 1, 0);
    

    最后,在您的请求/响应完成后,您需要保存 XML:

    TraceExtension.XmlRequest.Save(@"c:\temp\ForwardRequest.xml");
    TraceExtension.XmlResponse.Save(@"c:\temp\ForwardResponse{0}.xml");
    

    警告:这实际上是我过去通过 UPS 认证时使用的代码,但此代码只使用过一次。因此,它可能不是最好的质量、漂亮或其他非常有用的东西,除了那一件事。

    【讨论】:

      【解决方案2】:

      对于那些像我一样苦苦挣扎的人,如果您的 Request 和 Respose 都为 Null,则需要在实例化 ShipService 之前注册扩展。

      TraceExtension.RegisterSoapExtension( typeof( TraceExtension ), 1, 0 ); ShipService shpSvc = new ShipService();

      希望这对某人有所帮助:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-02
        • 1970-01-01
        • 2021-04-15
        • 2013-03-19
        • 1970-01-01
        相关资源
        最近更新 更多