将值传递给SOAP API复杂类型

时间:2015-04-10 13:27:26

标签: c# web-services soap casting wsdl

我使用服务器参考调用SOAP API,有一种需要权重值的复杂类型。我使用以下代码设置值:

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;

响应返回并且错误说明"无效的重量"。以下是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>

当我使用SOAPUI进行调用时,调用完成而没有错误。下面是完整的代码,我现在正在对这些值进行硬编码以完成我的测试,因此任何建议都必须考虑到我将从数据库值中填充的事实。

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);

    }
}

运行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>

1 个答案:

答案 0 :(得分:0)

我有一种感觉,问题有一个简单的解决方案,我忽略了。每个十进制字段都有一个以Specified结尾的相应字段。 Specified字段是一个布尔值,必须设置为true才能在序列化期间发送字段值。还有一些帖子(XmlSerializer, "Specified" suffix and IReflect)定义了更好的实现方法;现在我手动指定:

    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",
    };

如果我花了一点时间查看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");
    }
}

希望这有帮助。