【问题标题】:WCF request with default empty tags带有默认空标签的 WCF 请求
【发布时间】:2013-04-27 20:05:57
【问题描述】:

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

但是,当我尝试使用普通 C# 项目,使用 VS2010 生成的代理类来执行此操作时,请求似乎不完整,因为空标签不在请求中。然后我得到一个 "This is an operation implementation generated fault" 错误,在 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" }
                   }
               }
           });

【问题讨论】:

    标签: wcf ssl xsd wsdl


    【解决方案1】:

    在您的代码中,您生成的是ContractCancellationRequestEnvelopePortaal_Content 部分,而不是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。

    【讨论】:

    • 这些是服务引用创建的类。我看不出我应该如何撰写邮件?
    • @Mortana - 我刚刚注意到您似乎正在使用服务参考,我会尽快更新我的答案以反映这一点。我希望也有业务标题的类。给我几分钟,我会用建议更新我的答案。
    • 谢谢蒂姆!解决方案是提供 WSDL 中指定的每个必需元素。我现在可以成功地与网络服务通信了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多