我有一個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();
}
}
}
可能是這樣,但錯誤表示代碼需要完全信任,這在SQL CLR中是不可能的。通常調用一個Web服務需要EXTERNAL權限,用於程序集和數據庫所有者,但如果這是問題,則不會在此處報告異常。 – 2012-03-20 13:14:27
我已將觸發器項目的「權限級別」更改爲「不安全」,但沒有任何更改 – Aaaaaaaa 2012-03-20 13:17:21
我認爲問題的根源可能在於WCF正在動態創建程序集以充當服務代理。這可能是爲什麼這個代碼需要一個完整的信任環境。如果SQLCLR不能配置爲完全信任(我對SQLCLR瞭解不多),那麼您將無法運行代碼。 – 2012-03-20 13:30:10