2012-03-20 61 views
1

我有一个CLR SQL触发器,试图以下articleCLR触发异常,当尝试使用WCF服务

的基础上与WCF服务进行通信。当我尝试更新/插入一条记录沟通,我得到以下异常:

No row was updated.  
The data in row 1 was not committed.  
Error Source: .Net SqlClient Data Provider.  
Error Message: A .NET Framework error occured during execution of a user-defined routine or aggregate "WCFTrigger": System.Security.HostProtectionException: Attempt to perform an operation that was forbidden by the CLR host.  
The protected resource (only available with full trust) where: All  
The demanded resources were: Synchronization, ExternalThreading  
System.Security.HostProtectionException:  
    at System.ServiceModel.Description.TypeLoader.LoadContractDescriptionHelper(Type ContactType, Type ServiceType, Object serviceImplementation)  
    at System.ServiceModel.ChannelFactory '1.CreateDescription()  
    at System.ServiceModel.ChannelFactory.InitializeEndpoint(Binding binding, 
EndpointAddress address)  
    at System.ServiceModel.ChannelFactory '1..ctor(Binding binding, EndpointAddress address)  
    at System.ServiceModel.ClientBase '1..ctor(Binding binding, EndpointAddress address)  
    at ServiceClient.WCFServiceReference.ServiceContractClient..ctor(Binding binding, 
EndpointAddress address) 

主机就像在文章中,客户端的app.config

<?xml version="1.0"?> 
<configuration> 
    <system.serviceModel> 
     <bindings> 
      <wsHttpBinding> 
       <binding name="WSHttpBinding_IServiceContract" 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="Text" 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="Windows" negotiateServiceCredential="true" algorithmSuite="Default"/> 
        </security> 
       </binding> 
      </wsHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="http://localhost:8000/services/MyService" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServiceContract" contract="WCFServiceReference.IServiceContract" name="WSHttpBinding_IServiceContract"> 
       <identity> 
        <userPrincipalName value="[email protected]"/> 
       </identity> 
      </endpoint> 
     </client> 
    </system.serviceModel> 
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration> 

有谁知道,什么那是为什么?


触发的代码:

public partial class Triggers { 
    [SqlProcedure()] 
    public static void SendData(String crudType) { 
     EndpointAddress endpoint = new EndpointAddress(new Uri("http://localhost:8000/services/myservice")); 
     WSHttpBinding httpBinding = new WSHttpBinding(); 
     ServiceClient.WCFServiceReference.ServiceContractClient myClient = new ServiceClient.WCFServiceReference.ServiceContractClient(httpBinding, endpoint); 

      switch(crudType) { 
       case "Update": 
        myClient.UpdateOccured(); 
        break; 
       case "Insert": 
        myClient.InsertOccured(); 
        break; 
     } 
    } 

    [Microsoft.SqlServer.Server.SqlTrigger(Name = "WCFTrigger", 
     Target = "tbCR", Event = "FOR UPDATE, INSERT")] 
    public static void Trigger1() { 
     SqlTriggerContext myContext = SqlContext.TriggerContext; 

     switch(myContext.TriggerAction) { 
      case TriggerAction.Update: 
       SendData("Update"); 
       break; 
      case TriggerAction.Insert: 
       SendData("Insert"); 
       break; 
     } 
    } 
} 

代理:

namespace ServiceClient.WCFServiceReference { 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="WCFServiceReference.IServiceContract")] 
    public interface IServiceContract { 

     [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IServiceContract/UpdateOccured", ReplyAction="http://tempuri.org/IServiceContract/UpdateOccuredResponse")] 
     void UpdateOccured(); 

     [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IServiceContract/InsertOccured", ReplyAction="http://tempuri.org/IServiceContract/InsertOccuredResponse")] 
     void InsertOccured(); 
    } 

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    public interface IServiceContractChannel : ServiceClient.WCFServiceReference.IServiceContract, System.ServiceModel.IClientChannel { 
    } 

    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
    public partial class ServiceContractClient : System.ServiceModel.ClientBase<ServiceClient.WCFServiceReference.IServiceContract>, ServiceClient.WCFServiceReference.IServiceContract { 

     public ServiceContractClient() { 
     } 

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

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

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

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

     public void UpdateOccured() { 
      base.Channel.UpdateOccured(); 
     } 

     public void InsertOccured() { 
      base.Channel.InsertOccured(); 
     } 
    } 
} 

回答

2

此问题是由部分信任代码访问安全(CAS)设置下在SQL Server中运行.NET代码(WCF客户端调用服务)引起的。查看有关为SQL Server配置CAS的MSDN article

编辑:

作为替代,能够完全信任,配置在WCF服务的WebHttpBinding端点。使用System.Net HttpWebRequest & HttpWebResponse类调​​用服务以避免使用基于WCF ChannelFactory的管道。

+0

可能是这样,但错误表示代码需要完全信任,这在SQL CLR中是不可能的。通常调用一个Web服务需要EXTERNAL权限,用于程序集和数据库所有者,但如果这是问题,则不会在此处报告异常。 – 2012-03-20 13:14:27

+0

我已将触发器项目的“权限级别”更改为“不安全”,但没有任何更改 – Aaaaaaaa 2012-03-20 13:17:21

+0

我认为问题的根源可能在于WCF正在动态创建程序集以充当服务代理。这可能是为什么这个代码需要一个完整的信任环境。如果SQLCLR不能配置为完全信任(我对SQLCLR了解不多),那么您将无法运行代码。 – 2012-03-20 13:30:10

1

你不能做任何事情,任何SQLCLR组件多线程和异常告诉你,你是试图使用线程。你是否异步调用WCF服务?

我会推荐从SQLCLR触发器发布您的代码以获取更多帮助。

从SQL CLR调用WCF服务调用asmx Web服务要困难得多,您确定需要wcf吗?

+0

不,在“服务参考设置”中“生成异步操作”未被选中,并且从触发器中同步调用“发送数据”! – Aaaaaaaa 2012-03-20 12:52:50

+0

“需要的资源是:同步,ExternalThreading”似乎表明您的代码中有某些东西,或者生成的代理尝试执行多线程操作。上次我尝试通过SQL CLR触发器来使用WCF时,我放弃了并创建了一个asmx Web服务,它工作得很好。这是一个选项,也请发布您的触发代码。 – 2012-03-20 12:56:53

+0

嗯在进一步检查它可能是与您的wcf服务,而不是您的SQL CLR触发器,因为错误似乎不会发生在您的触发器,但在WCF服务。你可以从简单的控制台应用程序调用服务吗? – 2012-03-20 13:23:36