我有一个使用Java Spring Boot开发的SOAP 1.1服务,它对我的任何请求都没有任何问题,并提供有效的SOAP响应。
现在的问题是,只要我将此服务作为服务引用添加到任何.NET / C#项目,引用就会被创建,我可以发送请求,但响应(肯定是从我的SOAP服务发送的)无法映射回来并且我的.NET应用程序中的对象始终为null。
我已经发现问题可能是什么但我不确切地知道如何(如果甚至可能这样)改变我的xsd / wsdl以正确生成所有源。
首先,我的Java Spring Boot项目中的.xsd用于生成WSDL和服务参考:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://atu.de/soaptransformer/base"
xmlns:tns="http://atu.de/soaptransformer/base"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="1.0">
<xs:complexType name="ArrayOfMessages">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="message" nillable="true"
type="tns:AppDataMessageData"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AppDataMessageData">
<xs:sequence>
<xs:element name="messageCode" type="xs:int"/>
<xs:element name="messageText" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AppDataMessageData" nillable="true" type="tns:AppDataMessageData"/>
<xs:complexType name="AppDataHeaderData">
<xs:sequence>
<xs:element name="authorization" type="xs:string"/>
<xs:element name="branchNumber" type="xs:string"/>
<xs:element name="mainSystemOrderNumber" type="xs:string"/>
<xs:element name="callMode" type="xs:string"/>
<xs:element name="damageType" type="xs:string"/>
<xs:element name="misc1" type="xs:string"/>
<xs:element name="misc2" type="xs:string"/>
<xs:element name="countryRegionId" type="xs:string"/>
<xs:element name="messages" type="tns:ArrayOfMessages"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AppDataHeaderData" nillable="true" type="tns:AppDataHeaderData"/>
<xs:complexType name="ArrayOfPositions">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="position" nillable="true"
type="tns:AppDataPositionData"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AppDataPositionData">
<xs:sequence>
<xs:element name="inventTransId" type="xs:string"/>
<xs:element name="positionNumber" type="xs:int"/>
<xs:element name="itemId" type="xs:string"/>
<xs:element name="itemType" type="xs:string"/>
<xs:element name="articleDescription" type="xs:string"/>
<xs:element name="deleteFlag" type="xs:boolean"/>
<xs:element name="itemPosType" type="xs:string"/>
<xs:element name="itemParentId" type="xs:string"/>
<xs:element name="installDuration" type="xs:double"/>
<xs:element name="misc" type="xs:string"/>
<xs:element name="messages" type="tns:ArrayOfMessages"/>
<xs:element name="quantity" type="xs:double"/>
<xs:element name="salesPrice" type="xs:double"/>
<xs:element name="lineDiscAuto" type="xs:double"/>
<xs:element name="lineDiscMan" type="xs:double"/>
<xs:element name="lineDiscEmpl" type="xs:double"/>
<xs:element name="lineAmount" type="xs:double"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AppDataPositionData" nillable="true" type="tns:AppDataPositionData"/>
<xs:complexType name="AppDataInsuranceData">
<xs:sequence>
<xs:element name="retention" type="xs:double"/>
<xs:element name="policyNumber" type="xs:string"/>
<xs:element name="lossNumber" type="xs:string"/>
<xs:element name="directPlacing" type="xs:boolean"/>
<xs:element name="inputTaxDeduction" type="xs:boolean"/>
<xs:element name="lossDate" type="xs:string"/>
<xs:element name="arranger" type="xs:string"/>
<xs:element name="retentionRenounceWorkshop" type="xs:double"/>
<xs:element name="retentionRenounceInsurance" type="xs:double"/>
<xs:element name="transmitted" type="xs:boolean"/>
<xs:element name="automatedCDVProvided" type="xs:boolean"/>
<xs:element name="insuranceDamageCauseDesc" type="xs:string"/>
<xs:element name="insuranceDamageDesc" type="xs:string"/>
<xs:element name="costCovered" type="xs:boolean"/>
<xs:element name="costCoveringCheckState" type="xs:string"/>
<xs:element name="messages" type="tns:ArrayOfMessages"/>
<xs:element name="directPayer" type="xs:boolean"/>
<xs:element name="insuranceDamageType" type="xs:string"/>
<xs:element name="insuranceDebitorNumber" type="xs:int"/>
<xs:element name="insuranceName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AppDataInsuranceData" nillable="true" type="tns:AppDataInsuranceData"/>
<xs:complexType name="AppDataCustomerData">
<xs:sequence>
<xs:element name="custAccount" type="xs:string"/>
<xs:element name="custAccountDBM" type="xs:string"/>
<xs:element name="authorizationId" type="xs:string"/>
<xs:element name="noticeId" type="xs:string"/>
<xs:element name="flagDNEPost" type="xs:boolean"/>
<xs:element name="flagDNEElec" type="xs:boolean"/>
<xs:element name="custGroup" type="xs:string"/>
<xs:element name="approvalNo" type="xs:string"/>
<xs:element name="leasingNo" type="xs:string"/>
<xs:element name="messages" type="tns:ArrayOfMessages"/>
<xs:element name="salutation" type="xs:string"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="lastName" type="xs:string"/>
<xs:element name="company" type="xs:string"/>
<xs:element name="zipCode" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="street" type="xs:string"/>
<xs:element name="addressHouseNumber" type="xs:string"/>
<xs:element name="addressHouseNumberAdd" type="xs:string"/>
<xs:element name="phone" type="xs:string"/>
<xs:element name="mobil" type="xs:string"/>
<xs:element name="telefax" type="xs:string"/>
<xs:element name="email" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AppDataCustomerData" nillable="true" type="tns:AppDataCustomerData"/>
<xs:complexType name="AppDataVehicleData">
<xs:sequence>
<xs:element name="vehicleId" type="xs:string"/>
<xs:element name="licenseNumber" type="xs:string"/>
<xs:element name="vin" type="xs:string"/>
<xs:element name="atuKtypNr" type="xs:int"/>
<xs:element name="tecDocKtypNr" type="xs:int"/>
<xs:element name="kba1" type="xs:string"/>
<xs:element name="kba2" type="xs:string"/>
<xs:element name="kba3" type="xs:string"/>
<xs:element name="kba32" type="xs:string"/>
<xs:element name="natCode" type="xs:string"/>
<xs:element name="mileage" type="xs:int"/>
<xs:element name="registrationDate" type="xs:string"/>
<xs:element name="categoryId" type="xs:string"/>
<xs:element name="manufacturerName" type="xs:string"/>
<xs:element name="modelName" type="xs:string"/>
<xs:element name="messages" type="tns:ArrayOfMessages"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AppDataVehicleData" nillable="true" type="tns:AppDataVehicleData"/>
<xs:complexType name="AppDataMiscData">
<xs:sequence>
<xs:element name="EmplName" type="xs:string"/>
<xs:element name="messages" type="tns:ArrayOfMessages"/>
<xs:element name="IntDummy_1" type="xs:int"/>
<xs:element name="IntDummy_2" type="xs:int"/>
<xs:element name="IntDummy_3" type="xs:int"/>
<xs:element name="IntDummy_4" type="xs:int"/>
<xs:element name="IntDummy_5" type="xs:int"/>
<xs:element name="DoubleDummy_1" type="xs:double"/>
<xs:element name="DoubleDummy_2" type="xs:double"/>
<xs:element name="DoubleDummy_3" type="xs:double"/>
<xs:element name="DoubleDummy_4" type="xs:double"/>
<xs:element name="DoubleDummy_5" type="xs:double"/>
<xs:element name="StringDummy_1" type="xs:string"/>
<xs:element name="StringDummy_2" type="xs:string"/>
<xs:element name="StringDummy_3" type="xs:string"/>
<xs:element name="StringDummy_4" type="xs:string"/>
<xs:element name="StringDummy_5" type="xs:string"/>
<xs:element name="BooleanDummy_1" type="xs:boolean"/>
<xs:element name="BooleanDummy_2" type="xs:boolean"/>
<xs:element name="BooleanDummy_3" type="xs:boolean"/>
<xs:element name="BooleanDummy_4" type="xs:boolean"/>
<xs:element name="BooleanDummy_5" type="xs:boolean"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AppDataMiscData" nillable="true" type="tns:AppDataMiscData"/>
<xs:complexType name="ArrayOfAdditionals">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="additional" nillable="true"
type="tns:AppDataAdditionalData"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AppDataAdditionalData">
<xs:sequence>
<xs:element name="data1" type="xs:string"/>
<xs:element name="data2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AppDataAdditionalData" nillable="true" type="tns:AppDataAdditionalData"/>
<xs:complexType name="AppDataDataRequest">
<xs:sequence>
<xs:element name="headerData" type="tns:AppDataHeaderData"/>
<xs:element name="positions" type="tns:ArrayOfPositions"/>
<xs:element name="insuranceData" type="tns:AppDataInsuranceData"/>
<xs:element name="customerData" type="tns:AppDataCustomerData"/>
<xs:element name="vehicleData" type="tns:AppDataVehicleData"/>
<xs:element name="miscData" type="tns:AppDataMiscData" form="unqualified"/>
<xs:element name="additionals" type="tns:ArrayOfAdditionals" form="unqualified"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="processingRequest">
<xs:sequence>
<xs:element name="AppDataDataRequest" type="tns:AppDataDataRequest"/>
</xs:sequence>
</xs:complexType>
<xs:element name="processingRequest" nillable="true" type="tns:processingRequest"/>
<xs:complexType name="AppDataDataResult">
<xs:sequence>
<xs:element name="headerData" type="tns:AppDataHeaderData"/>
<xs:element name="positions" type="tns:ArrayOfPositions"/>
<xs:element name="insuranceData" type="tns:AppDataInsuranceData"/>
<xs:element name="customerData" type="tns:AppDataCustomerData"/>
<xs:element name="vehicleData" type="tns:AppDataVehicleData"/>
<xs:element name="miscData" type="tns:AppDataMiscData"/>
<xs:element name="additionals" type="tns:ArrayOfAdditionals"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="processingResponse">
<xs:sequence>
<xs:element name="AppDataDataResult" type="tns:AppDataDataResult"/>
</xs:sequence>
</xs:complexType>
<xs:element name="processingResponse" nillable="true" type="tns:AppDataDataResult"/>
</xs:schema>
以下是来自C#项目中Visual Studio生成的服务引用的代码:
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://atu.de/soaptransformer/base/processing", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlElementAttribute("processingResponse", Namespace="http://atu.de/soaptransformer/base", IsNullable=true)]
public processingResponse processing([System.Xml.Serialization.XmlElementAttribute(Namespace="http://atu.de/soaptransformer/base", IsNullable=true)] processingRequest processingRequest) {
object[] results = this.Invoke("processing", new object[] {
processingRequest});
return ((processingResponse)(results[0]));
}
我发现如果我更改以下行
[return: System.Xml.Serialization.XmlElementAttribute("processingResponse", Namespace="http://atu.de/soaptransformer/base", IsNullable=true)]
并添加“Form = System.Xml.Schema.XmlSchemaForm.Unqualified”:
[return: System.Xml.Serialization.XmlElementAttribute("processingResponse", Namespace="http://atu.de/soaptransformer/base", IsNullable=true, Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
响应被正确映射到我的对象,它似乎在没有任何问题的情况下正常工作。
问题是我想改变我的.xsd从一开始就正确生成这些源 - 我已经尝试将Form = Unqualified添加到“processingResponse”complexType中的“AppDataDataResult”元素但它不起作用。
直接将此属性添加到processingResponse元素也不起作用,因为它不可能导致在架构定义/标记下面一层。
我没有找到任何解决这个问题的具体方法,因为它似乎与Spring Boot Framework Java非常具体,并且生成了wsdl。
我希望有人可以帮助我解决这个问题,因为它似乎不是一个大问题(它的“唯一”属性需要在生成源代码时添加)但我似乎无法找到解决方案。在此先感谢您的帮助!
我找到了问题,这是一个非常简单的修复此问题 - 在我的Spring Boot项目中,我返回JAXBElements,响应的参数是“QName”,表示响应的对象。这里的问题是SOAP-Response没有相关的命名空间来在.NET中生成Sources期间识别Object。所以我将正确的Namespace-URI添加到QName-Object,现在对象得到解析并返回正确的响应:
final QName qname = new QName(NAMESPACE_URI, "processingResponse");
return new JAXBElement<>(qname, ProcessingResponse.class, processingResponse);
最后这是一个非常愚蠢/简单的问题,但我尝试了其他一切,但没有尝试最明显/最简单。