【问题标题】:Issues with some remote sites sending binary data over WCF一些远程站点通过 WCF 发送二进制数据的问题
【发布时间】:2011-10-19 17:42:17
【问题描述】:

我遇到的这个问题并不总是发生,但对于特定的 WCF 客户端,我正在记录以下异常:

System.ServiceModel.Security.MessageSecurityException

从对方收到不安全或不正确安全的故障 派对。故障代码和细节见内部FaultException。

System.ServiceModel.Security.MessageSecurityException:不安全或 从另一方收到不正确的安全故障。见 故障代码和详细信息的内部 FaultException。 ---> System.ServiceModel.FaultException:验证时出错 消息的安全性。 --- 内部异常堆栈跟踪结束 --- 服务器堆栈跟踪:在 System.ServiceModel.Security.SecuritySessionClientSettings1.SecurityRequestSessionChannel.ProcessReply(Message reply, TimeSpan timeout, SecurityProtocolCorrelationState correlationState) at System.ServiceModel.Security.SecuritySessionClientSettings1.SecurityRequestSessionChannel.Request(Message 消息,TimeSpan 超时)在 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息 消息,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.Call(字符串动作, Boolean oneway, ProxyOperationRuntime 操作, Object[] ins, Object[] 出局,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.Call(字符串动作, Boolean oneway, ProxyOperationRuntime 操作, Object[] ins, 对象 [] 出局)在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime 操作)在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息)在 [0] 处重新抛出异常:在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg)在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(消息数据& msgData,Int32 类型)在 Proxy.ExecutionResultsUpdateService.IExecutionResultsUpdateService.SaveBinaryResults(SaveBinaryResultsRequest 请求)在 Proxy.ExecutionResultsUpdateService.ExecutionResultsUpdateServiceClient。 > Proxy.ExecutionResultsUpdateService.IExecutionResultsUpdateService.SaveBinaryResults(SaveBinaryResultsRequest 请求) LoggingExecutionResultsUpdateServiceClient.SaveBinaryResults(SaveBinaryResultsRequest 请求)在 ClientServices.ResultsController.Send(IEnumerable`1 resultsList) 在 NMA.StartAutomaticAgent() 在 MainApplication.Start()

客户端正在抛出该异常。

SaveBinaryResults 的服务代码是:

[ServiceContract(Name="IExecutionResultsUpdateService")]
public interface IExecutionResultsUpdateService_v1_0_1 : IExecutionResultsUpdateService
{
    [OperationContract(Name="SaveBinaryResults")]
    void SaveSQLResults(byte[] data, string serverXml, Guid clientInstanceId, int moduleId, Guid batchIdentifier);
}

   public void SaveSQLResults(byte[] data, string serverXml, Guid clientInstanceId, int moduleId, Guid batchIdentifier)
    {
        DataSet dataSet = (DataSet)new BinaryFormatter().Deserialize(new MemoryStream(data));

        try
        {
            XmlDocument serverDocument = new XmlDocument();
            serverDocument.LoadXml(serverXml);

            executionResultsRepository.Save(dataSet, serverDocument);
            executionHistoryRepository.SaveModuleExecution(clientInstanceId, moduleId, true, null, batchIdentifier);
        }
        catch (System.Data.SqlClient.SqlException ex)
        {
            executionHistoryRepository.SaveModuleExecution(clientInstanceId, moduleId, false, ex.ToString(), batchIdentifier);
            throw new FaultException<System.Data.SqlClient.SqlException>(ex, new FaultReason(ex.Message));
        }
    }

IExecutionResultsUpdateService 的客户端代理配置为:

<binding name="WSHttpBinding_IExecutionResultsUpdateService"
  closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
  sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false"
  hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288"
  maxReceivedMessageSize="65536" messageEncoding="Mtom" textEncoding="utf-8"
  useDefaultWebProxy="true" allowCookies="false">
  <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
  <reliableSession ordered="true" inactivityTimeout="00:10:00"
    enabled="false" />
  <security mode="Message">
    <transport clientCredentialType="Windows" proxyCredentialType="None"
      realm="" />
    <message clientCredentialType="UserName" negotiateServiceCredential="true"
      algorithmSuite="Default" establishSecurityContext="true" />
  </security>
</binding>

服务配置是

<service behaviorConfiguration="ServiceBehavior" 
    name="Services.ExecutionResultsUpdateService">
    <endpoint binding="wsHttpBinding" 
      bindingConfiguration="MtomWsHttpBindingForBigArrays" 
      contract="Services.IExecutionResultsUpdateService_v1_0_1" 
      address="/ExecutionResults"/>
    <endpoint binding="wsHttpBinding" 
      bindingConfiguration="wsHttpBinding" 
      contract="Services.IExecutionResultsUpdateService_v1_0_1"/>
    <host>
      <baseAddresses>
      <add baseAddress="http://[ipaddress]/ExecutionResultsUpdateService.svc"/>
      </baseAddresses>
    </host>
</service>

   <binding name="MtomWsHttpBindingForBigArrays" 
         maxReceivedMessageSize="2147483647" 
         messageEncoding="Mtom" 
         receiveTimeout="5"              
         useDefaultWebProxy="false">
          <readerQuotas maxDepth="2147483647" 
             maxStringContentLength="2147483647" 
             maxArrayLength="2147483647" 
             maxBytesPerRead="2147483647" 
             maxNameTableCharCount="2147483647" />
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
    </binding>

客户端代理的一部分如下所示:

public interface IExecutionResultsUpdateService
{
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IExecutionResultsUpdateService/ReportPackageCompletion", ReplyAction="http://tempuri.org/IExecutionResultsUpdateService/ReportPackageCompletionResponse" +
        "")]
    [System.ServiceModel.XmlSerializerFormatAttribute()]
    void ReportPackageCompletion(string clientInstanceId, int packageId);

    // CODEGEN: Parameter 'data' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlElementAttribute'.
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IExecutionResultsUpdateService/SaveBinaryResults", ReplyAction="http://tempuri.org/IExecutionResultsUpdateService/SaveBinaryResultsResponse")]
    [System.ServiceModel.XmlSerializerFormatAttribute()]
    Proxy.ExecutionResultsUpdateService.SaveBinaryResultsResponse SaveBinaryResults(Proxy.ExecutionResultsUpdateService.SaveBinaryResultsRequest request);
}

注意:两个端点是因为我必须支持这个服务的两个版本。具有绑定“MtomWsHttpBindingForBigArrays”的服务是导致我的问题的服务。 (另一个做同样的事情,但接受一个 DataSet 作为参数,除了一个 byte[],我很快发现这是低效和不好的做法。)

有谁知道摆脱这个异常是否在我的控制范围内?我可以对客户端或服务配置文件进行任何配置更改吗?

如果您需要我的更多信息,请告诉我。

【问题讨论】:

  • 这些客户端发送的数据有多大?这些客户是在不同的时区还是有一些时间问题?
  • 数据不是很大。几个 MB 最大。

标签: c# wcf


【解决方案1】:

每次这些客户端进行调用时都会引发错误吗?如果是,请检查客户端上的时钟/时区/日期。

【讨论】:

  • 在美国各地都有客户。是的。每次生成该异常的客户端并且它们确实出现在另一个时区时,都会发生这种情况。
  • 只需确保该特定客户的时区/日期/时间正确无误。休息时间超过 5 分钟,通话将失败。此外,如果您可以 vnc 进入客户端机器,请尝试 ping 您的服务的基本 URL,以查看机器是否可以到达那里。
  • 客户端调用肯定会到达服务,因为在此之前还有另一个服务调用成功,以及客户端错误信息是使用另一个 wcf 客户端代理发回的事实。
  • 尝试禁用消息安全,看看它是否仍然发送错误。可能是用户名错误。
  • 用户名和密码在解密后直接在代码中提供。客户端和这些服务之间没有人工交互。我生成的代理与应用程序一起分发并自动执行
猜你喜欢
  • 2011-10-14
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多