我有一个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