简体   繁体   English

将值传递给SOAP API复杂类型

[英]Pass value to SOAP API complex type

I'm calling a SOAP API using Server Reference, there is a complex type which requires weight values. 我使用服务器参考调用SOAP API,有一个复杂的类型需要权重值。 I'm setting the values using the following code: 我使用以下代码设置值:

parcel objpcl = new parcel();
objpcl.weight = 10;
objpcl.length = 10;
objpcl.width = 10;
objpcl.depth = 10;
objpcl.girth = 10;
objpcl.combinedDimension = 10;
objpcl.volume = 10;
objpcl.value = 100;

The response returns and error stating "Invalid Weight". 响应返回并指出“ Invalid Weight”错误。 Here are the WSDL details: 以下是WSDL的详细信息:

  <xs:complexType name="parcel">
    <xs:sequence>
      <xs:element minOccurs="0" name="weight" type="xs:decimal" />
      <xs:element minOccurs="0" name="length" type="xs:decimal" />
      <xs:element minOccurs="0" name="width" type="xs:decimal" />
      <xs:element minOccurs="0" name="depth" type="xs:decimal" />
      <xs:element minOccurs="0" name="girth" type="xs:decimal" />
      <xs:element minOccurs="0" name="combinedDimension" type="xs:decimal" />
      <xs:element minOccurs="0" name="volume" type="xs:decimal" />
      <xs:element minOccurs="0" name="currency" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="xs:decimal" />
      <xs:element minOccurs="0" name="numberOfParts" type="xs:decimal" />
      <xs:element minOccurs="0" name="numberOfItems" type="xs:decimal" />
      <xs:element minOccurs="0" name="hangingGarment" type="xs:boolean" />
      <xs:element minOccurs="0" name="theftRisk" type="xs:boolean" />
      <xs:element minOccurs="0" name="multipleParts" type="xs:boolean" />
      <xs:element minOccurs="0" name="catalogue" type="xs:boolean" />
      <xs:element minOccurs="0" name="description" type="xs:string" />
      <xs:element minOccurs="0" name="originOfParcel" type="xs:string" />
    </xs:sequence>
  </xs:complexType>

When I make the call using SOAPUI the call completes without an error. 当我使用SOAPUI进行呼叫时,呼叫会完成而不会出现错误。 Below is the complete code, I'm hard coding the values for now to complete my testing, so any recommendation will have to account for the fact that I will be populating from database values. 下面是完整的代码,现在我正在对值进行硬编码以完成测试,因此任何建议都必须考虑到我将从数据库值中进行填充的事实。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using HermesWebService;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        RoutingWebServiceClient objHermesWebService = new RoutingWebServiceClient();
        objHermesWebService.ClientCredentials.UserName.UserName = "ababab";
        objHermesWebService.ClientCredentials.UserName.Password = "abababa";

        deliveryRoutingRequest objRoutingRequest = new deliveryRoutingRequest();
        objRoutingRequest.clientId = "aba";
        objRoutingRequest.clientName = "aba";
        objRoutingRequest.userId = "abababa";
        objRoutingRequest.sourceOfRequest = "ababab";

        delRoutingRequestEntry objReqEntry = new delRoutingRequestEntry();
                objReqEntry.expectedDespatchDate = Convert.ToDateTime("2015-04-10T00:00:00");
    objReqEntry.countryOfOrigin = "US";

        customer objCust = new customer();
        objCust.customerReference1 = "12345";

        address objadr = new address();
        objadr.lastName = "Robinson";
        objadr.streetName = "Eastern Perimeter Road";
        objadr.addressLine1 = "London Heathrow Airport";
        objadr.city = "London";
        objadr.region = "Hounslow";
        objadr.postCode = "TW6 2GE";
        objadr.countryCode = "GB";

        parcel objpcl = new parcel();
        objpcl.weight = 10m;
        objpcl.length = 10m;
        objpcl.width = 10m;
        objpcl.depth = 10m;
        objpcl.girth = 10m;
        objpcl.combinedDimension = 10m;
        objpcl.volume = 10m;
        objpcl.value = 100;

        objCust.address = objadr;
        objReqEntry.customer = objCust;
        objReqEntry.parcel = objpcl;

        objRoutingRequest.deliveryRoutingRequestEntries = new [] {objReqEntry};


        //var request = new delroutingrequestentry
        //{
        //    addressvalidationrequired = false
        //};

        //request.parcel = objpcl;
        //objroutingrequest.deliveryroutingrequestentries[0] = request;

        var x = objHermesWebService.validateDeliveryAddress(objRoutingRequest);

    }
}

After running the Microsoft Service Trace Viewer it appears that the Parcel element is not making it to the API call, here is a copy of part of the trace viewer log: 运行Microsoft Service Trace Viewer后,似乎Parcel元素未将其加入API调用,这是跟踪查看器日志的一部分的副本:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<ActivityId CorrelationId="58ef72b0-fd4d-475f-9347-5f1ba25f5987" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">7f7337fb-8db5-4b84-8e6c-44d7f43d561a</ActivityId>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<validateDeliveryAddress xmlns="http://v2.web.domain.routing.hermes.co.uk/">
<deliveryRoutingRequest>
<clientId xmlns="">aba</clientId>
<clientName xmlns="">aba</clientName>
<userId xmlns="">ababab</userId>
<sourceOfRequest xmlns="">ababab</sourceOfRequest>
<deliveryRoutingRequestEntries xmlns="">
<deliveryRoutingRequestEntry>
<customer>
<address>
<lastName>Robinson</lastName>
<streetName>Eastern Perimeter Road</streetName>
<addressLine1>London Heathrow Airport</addressLine1>
<city>London</city>
<region>Hounslow</region>
<postCode>TW6 2GE</postCode>
<countryCode>GB</countryCode>
</address>
<customerReference1>12345</customerReference1>
</customer>
<parcel></parcel>
<expectedDespatchDate>2015-04-10</expectedDespatchDate>
<countryOfOrigin>US</countryOfOrigin>
</deliveryRoutingRequestEntry>
</deliveryRoutingRequestEntries>
</deliveryRoutingRequest>
</validateDeliveryAddress>
</s:Body>
</s:Envelope>

I had a feeling the problem had a simple solution that I was overlooking. 我感到这个问题有一个我忽略的简单解决方案。 Each decimal field has a corresponding field which ends in Specified. 每个十进制字段都有一个对应的字段,以Specified结尾。 The Specified field is a boolean which must be set to true in order for the field value to be sent during the serialization. Specified字段是一个布尔值,必须将其设置为true才能在序列化期间发送该字段值。 There are additional post ( XmlSerializer, "Specified" suffix and IReflect ) which define better ways of accomplishing this; 还有其他文章( XmlSerializer,“ Specified”后缀和IReflect )定义了实现此目的的更好方法; for now I manually specify: 现在,我手动指定:

    var objpcl = new parcel
    {
        weight = 10, weightSpecified = true,
        length = 10, lengthSpecified = true,
        width = 10, widthSpecified = true,
        depth = 10, depthSpecified = true, 
        girth = 10, girthSpecified = true,
        combinedDimension = 10, combinedDimensionSpecified = true,
        volume = 10, volumeSpecified = true,
        value = 100, valueSpecified = true,
        numberOfParts = 1, numberOfPartsSpecified = true,
        numberOfItems = 10, numberOfItemsSpecified = true,            
        description = "Test Package",
        originOfParcel = "US",
    };

If I spent a little more time reviewing the WSDL file I would have noticed the following: 如果我花更多的时间查看WSDL文件,我会注意到以下内容:

    [XmlElement(Form = XmlSchemaForm.Unqualified, Order = 0)]
    public decimal weight { get; set; }
    [XmlIgnore]
    public bool weightSpecified { get; set; }

/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool weightSpecified
{
    get
    {
        return this.weightFieldSpecified;
    }
    set
    {
        this.weightFieldSpecified = value;
        this.RaisePropertyChanged("weightSpecified");
    }
}

Hope this helps. 希望这可以帮助。

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

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