首页 > 解决方案 > 由于 xml 声明,WCF 服务无法接收肥皂请求

问题描述

我编写了一个 WCF 服务,它在 C# 中充当事件接收器。客户端向事件接收器发送以下 Soap 请求:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:sila="http://sila.coop" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <SOAP-ENV:Body>
      <ResponseEvent xmlns="http://sila.coop">
         <requestId>10</requestId>
         <returnValue>
            <returnCode>3</returnCode>
            <message>command 'Reset' completed successfully</message>
            <duration>PT0S</duration>
            <deviceClass>8</deviceClass>
         </returnValue>
         <responseData>&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;ResponseData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sila.coop//schemata/ResponseType_1.2.xsd"&gt;&lt;/ResponseData&gt;</responseData>
      </ResponseEvent>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

这个被拒绝了,在服务跟踪查看器中我可以看到抛出了一个异常:

System.ServiceModel.ProtocolException, System.Xml.XmlException, 
system.xml.xmlexception data at the root level is invalid. line 1 position 1

当我启动 WCF 测试客户端时,我可以发送一个请求,如下所示:

<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <ResponseEvent
            xmlns="http://sila.coop"
            xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <requestId>1</requestId>
            <returnValue>
                <returnCode>3</returnCode>
                <deviceClass>0</deviceClass>
            </returnValue>
        </ResponseEvent>
    </s:Body>
</s:Envelope>

这个正在工作,它将通过服务。

不幸的是,我无法更改客户端。那么我如何配置或更改我的服务,让它理解带有 xml 声明的最顶层请求呢?

我通过 svcutil 工具从 SoapUi 中现有的模拟服务生成了事件接收器的代码:

界面:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://sila.coop", ConfigurationName="EventReceiverSoap")]
public interface EventReceiverSoap
{

    [System.ServiceModel.OperationContractAttribute(Action="http://sila.coop/ResponseEvent", ReplyAction="*")]
    ResponseEventResponse ResponseEvent(ResponseEventRequest request);

}

我的 web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="sdt"
               type="System.Diagnostics.XmlWriterTraceListener"
               initializeData= "EventReceiverSoap.e2e" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

  <system.web>
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1"/>
  </system.web>


  <system.serviceModel>

    <bindings>
      <basicHttpBinding>
        <binding name="EventReceiverSoap" />
      </basicHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- Legen Sie die Werte unten vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Metadateninformationen zu vermeiden. -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"    externalMetadataLocation="../wsdl/ls.wsdl" />/>
          <!-- Damit in Fehlern Ausnahmedetails zum Debuggen angezeigt werden, legen Sie den Wert unten auf "true" fest. Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Ausnahmeinformationen zu vermeiden. -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

</configuration>

执行:

//[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class EventReceiverSoapClient : System.ServiceModel.ClientBase<EventReceiverSoap>, EventReceiverSoap
{

    public EventReceiverSoapClient()
    {
    }

    public EventReceiverSoapClient(string endpointConfigurationName) : 
            base(endpointConfigurationName)
    {
    }

    public EventReceiverSoapClient(string endpointConfigurationName, string remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public EventReceiverSoapClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public EventReceiverSoapClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(binding, remoteAddress)
    {
    }

    public ResponseEventResponse ResponseEvent(ResponseEventRequest request)
    {
        return base.Channel.ResponseEvent(request);
    }


}

标签: c#xmlwcfsoapservice

解决方案


推荐阅读