0

我正在尝试使用 TLS 连接到 SOAP 1.1 Web 服务。证书已正确设置,我可以与 Web 服务进行通信。

但是,当我尝试使用普通 C# 项目执行此操作时,使用 VS2010 生成的代理类,请求似乎不完整,因为空标签不在请求中。然后我得到一个“这是一个操作实现产生的错误”错误,可以在 Fiddler 中查看

如果我随后尝试使用 SoapUI 发起请求,我会从 web 服务获得成功的响应。

我使用 Fiddler 比较了这两个请求,我注意到 C# 请求非常简单,只发送在我的 C# 类中填写的元素。但是当我检查 SoapUI 请求时,这个请求包含了 WSDL/XSD 中定义的每个元素,即使它们是空的。

我试图了解如何配置 C# 客户端以包含空元素,以查看 Web 服务是否会接受我的请求,但是我无法找到这样的设置。

C# 请求响应:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
      <faultcode xmlns="">
        SOAP-ENV:Server
      </faultcode>
      <faultstring xmlns="">
        This is an operation implementation generated fault
      </faultstring>
      <faultactor xmlns=""/>
      <detail xmlns="">
        <ns:SOAPFault xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn:xxx:xxx:data:soapfault:1:standard" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">
          <ns:ErrorCode>2.0</ns:ErrorCode>
          <ns:ErrorText>XML schema validation error</ns:ErrorText>
          <ns:ErrorDetails>
            /{urn:xxx:xxx:service:contractcancellation:1:standard}ContractCancellationRequestEnvelope[1]/part1[1]/ContractCancellationRequestEnvelope[1]/BusinessDocumentHeader[1]/Destination[1] 
          </ns:ErrorDetails>
        </ns:SOAPFault>
      </detail>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

C# 请求:

POST xx HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:ContractCancellationRequestEnvelope"
Host: xx
Content-Length: 887
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ContractCancellationRequestEnvelope xmlns="urn:xxx:xxx:data:contractcancellationrequest:1:standard">
      <Portaal_Content>
        <Portaal_MeteringPoint>
          <EANID>xxx</EANID>
          <MPCommercialCharacteristics>
            <ContractCancellationDate>
              2013-11-15
            </ContractCancellationDate>
          </MPCommercialCharacteristics>
          <Portaal_Mutation>
            <Initiator>xxx</Initiator>
            <Dossier>
              <ID>TST0000001</ID>
            </Dossier>
          </Portaal_Mutation>
        </Portaal_MeteringPoint>
      </Portaal_Content>
    </ContractCancellationRequestEnvelope>
  </s:Body>
</s:Envelope>

SoapUI 请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:xxx:xxx:data:contractcancellationrequest:1:standard">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:ContractCancellationRequestEnvelope>
         <urn:BusinessDocumentHeader>
            <!--Optional:-->
            <urn:ContentHash>?</urn:ContentHash>
            <!--Optional:-->
            <urn:ConversationID>?</urn:ConversationID>
            <!--Optional:-->
            <urn:CorrelationID>?</urn:CorrelationID>
            <urn:CreationTimestamp>?</urn:CreationTimestamp>
            <!--Optional:-->
            <urn:DocumentID>?</urn:DocumentID>
            <!--Optional:-->
            <urn:ExpiresAt>?</urn:ExpiresAt>
            <urn:MessageID>?</urn:MessageID>
            <!--Optional:-->
            <urn:ProcessTypeID>?</urn:ProcessTypeID>
            <!--Optional:-->
            <urn:RepeatedRequest>?</urn:RepeatedRequest>
            <!--Optional:-->
            <urn:TestRequest>?</urn:TestRequest>
            <urn:Destination>
               <urn:Receiver>
                  <!--Optional:-->
                  <urn:Authority>?</urn:Authority>
                  <!--Optional:-->
                  <urn:ContactTypeIdentifier>?</urn:ContactTypeIdentifier>
                  <urn:ReceiverID>?</urn:ReceiverID>
               </urn:Receiver>
               <!--Optional:-->
               <urn:Service>
                  <!--Optional:-->
                  <urn:ServiceMethod>?</urn:ServiceMethod>
                  <!--Optional:-->
                  <urn:ServiceName>?</urn:ServiceName>
               </urn:Service>
            </urn:Destination>
            <!--Optional:-->
            <urn:Manifest>
               <urn:NumberofItems>?</urn:NumberofItems>
               <!--1 or more repetitions:-->
               <urn:ManifestItem>
                  <!--Optional:-->
                  <urn:Description>?</urn:Description>
                  <!--Optional:-->
                  <urn:LanguageCode>?</urn:LanguageCode>
                  <urn:MimeTypeQualifierCode>?</urn:MimeTypeQualifierCode>
                  <urn:UniformResourceIdentifier>?</urn:UniformResourceIdentifier>
               </urn:ManifestItem>
            </urn:Manifest>
            <urn:Source>
               <!--Optional:-->
               <urn:Authority>?</urn:Authority>
               <!--Optional:-->
               <urn:ContactTypeIdentifier>?</urn:ContactTypeIdentifier>
               <urn:SenderID>?</urn:SenderID>
            </urn:Source>
         </urn:BusinessDocumentHeader>
         <urn:Portaal_Content>
            <urn:Portaal_MeteringPoint>
               <urn:EANID>?</urn:EANID>
               <urn:MPCommercialCharacteristics>
                  <urn:ContractCancellationDate>?</urn:ContractCancellationDate>
               </urn:MPCommercialCharacteristics>
               <urn:Portaal_Mutation>
                  <!--Optional:-->
                  <urn:ExternalReference>?</urn:ExternalReference>
                  <urn:Initiator>?</urn:Initiator>
                  <!--Optional:-->
                  <urn:Dossier>
                     <urn:ID>?</urn:ID>
                  </urn:Dossier>
               </urn:Portaal_Mutation>
            </urn:Portaal_MeteringPoint>
         </urn:Portaal_Content>
      </urn:ContractCancellationRequestEnvelope>
   </soapenv:Body>
</soapenv:Envelope>

如您所见,SoapUI 请求要完整得多,即使元素为空。

C#代码(重要部分):

_binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
_binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

_endpoint = new EndpointAddress(endpointAddress + "xxx");

_proxy = new ContractCancellationPortTypeClient(_binding, _endpoint);
_proxy.ClientCredentials.ClientCertificate.SetCertificate(
       StoreLocation.LocalMachine,
       StoreName.My,
       X509FindType.FindBySubjectName,
       "xxx");
_proxy.ContractCancellation(new ContractCancellationRequestEnvelope()
       { Portaal_Content = new ContractCancellationRequestEnvelope_PC()
           { Portaal_MeteringPoint = new ContractCancellationRequestEnvelope_PC_PMP()
               { EANID = request.EanId,
                 MPCommercialCharacteristics = new ContractCancellationRequestEnvelope_PC_PMP_MPCC()
                   { ContractCancellationDate = request.ContractCancellationDate },
                 Portaal_Mutation = new ContractCancellationRequestEnvelope_PC_PMP_PM()
                   { Initiator = request.SupplierEanId,
                     Dossier = new ContractCancellationRequestEnvelope_PC_PMP_PM_Dossier()
                       { ID = "TST0000001" }
                   }
               }
           });
4

1 回答 1

1

在您的代码中,您正在生成 的Portaal_Content部分ContractCancellationRequestEnvelope,但不是该BusinessDocumentHeader部分。

如果您查看收到的错误(通过 C#),我敢打赌,该BusinessDocumentHeader部分中缺少一个或多个必需元素:

错误文本为XML schema validation error,错误详细信息为:

ContractCancellationRequestEnvelope[1]/part1[1]/ContractCancellationRequestEnvelope[1]/BusinessDocumentHeader[1]/Destination[1]

您需要确保所有必需的元素都存在于您的 SOAP 消息中。

编辑

这样的事情应该可以解决问题:

ContractCancellationRequestEnvelope reqMsg = new ContractCancellationRequestEnvelope();

reqMsg.BusinessDocumentHeader = new BusinessDocumentHeader()
    { CorrelationTimestamp = "?",
      MessageID = "?" };
reqMsg.BusinessDocumentHeader.Destination = new Destination();
reqMsg.BusinessDocumentHeader.Receiver = new Receiver()
    { ReceiverID = "?" };

等等。基本上,请确保创建所需的每个元素。

顺便说一句,您可以进行嵌套自动初始化(如您发布的代码中所示),为了便于阅读,我只是在示例中采用了更明确的路线。

服务的 WSDL 将告诉您什么是必需的或可选的。

如果您需要更多帮助,请提供服务的 URL 或发布 WSDL。

于 2013-04-27T23:01:49.867 回答