2012-03-20 57 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