Dynamics crm 如何安全地忽略Dynamics CRM插件中的错误?

Dynamics crm 如何安全地忽略Dynamics CRM插件中的错误?,dynamics-crm,dynamics-crm-2013,Dynamics Crm,Dynamics Crm 2013,我在执行某些操作的自定义实体的创建(同步,后期操作)上注册了一个CRM插件,我希望创建操作能够成功,尽管插件中有错误。出于性能原因,我还希望在创建记录时立即启动插件,因此不希望使插件异步。我通过执行以下操作实现了这一点: 公共类FooPlugin:IPlugin { 公共FooPlugin(字符串unsecureInfo,字符串secureInfo){} public void Execute(IServiceProvider服务提供程序) { 尝试 { //样板 var context=(IP

我在执行某些操作的自定义实体的创建(同步,后期操作)上注册了一个CRM插件,我希望创建操作能够成功,尽管插件中有错误。出于性能原因,我还希望在创建记录时立即启动插件,因此不希望使插件异步。我通过执行以下操作实现了这一点:

公共类FooPlugin:IPlugin
{
公共FooPlugin(字符串unsecureInfo,字符串secureInfo){}
public void Execute(IServiceProvider服务提供程序)
{
尝试
{
//样板
var context=(IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var serviceFactory=(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOOrganizationService=serviceFactory.CreateOrganizationService(context.UserId);
//省略了附加验证
var targetEntity=(实体)context.InputParameters[“Target”];
UpdateFrobber(服务,(实体引用)targetEntity[“new_frobbrid”]);
CreateFollowUpFlibber(服务、目标实体);
关闭实体(服务、目标实体);
}
捕获(例外情况除外)
{
//发送电子邮件,但不要重新引发异常
//因为我们不希望回滚事务失败。
尝试
{
SendEmailForException(例如,上下文);
}
捕获{}
}
}
}
但是,当发生错误时(例如,在
UpdateFrobber(…)
中),服务客户端会收到此异常:

System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: 
There is no active transaction. This error is usually caused by custom plug-ins
that ignore errors from service calls and continue processing.

Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ref ProxyRpc rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(ref MessageData msgData, Int32 type)
   at Microsoft.Xrm.Sdk.IOrganizationService.Create(Entity entity)
   at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.CreateCore(Entity entity)
   at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.Create(Entity entity)
   at Microsoft.Xrm.Client.Services.OrganizationService.<>c__DisplayClassd.<Create>b__c(IOrganizationService s)
   at Microsoft.Xrm.Client.Services.OrganizationService.InnerOrganizationService.UsingService(Func`2 action)
   at Microsoft.Xrm.Client.Services.OrganizationService.Create(Entity entity)
   at MyClientCode() in MyClientCode.cs: line 100
System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]:
没有活动事务。此错误通常由自定义插件引起
忽略服务调用中的错误并继续处理。
服务器堆栈跟踪:
位于System.ServiceModel.Channels.ServiceChannel.HandlerReply(ProxyOperationRuntime操作,参考ProxyRpc rpc)
在System.ServiceModel.Channels.ServiceChannel.Call(字符串操作、布尔单向、ProxyOperationRuntime操作、对象[]输入、对象[]输出、时间跨度超时)
位于System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage方法调用,ProxyOperationRuntime操作)
位于System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage消息)
在[0]处重试异常:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg)
at System.Runtime.Remoting.proxy.RealProxy.PrivateInvoke(ref MessageData msgData,Int32类型)
位于Microsoft.Xrm.Sdk.IOrganizationService.Create(实体)
位于Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.CreateCore(实体)
位于Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.Create(实体)
在Microsoft.Xrm.Client.Services.OrganizationService.c__DisplayClassd.b__c(iOrganizations服务)上
位于Microsoft.Xrm.Client.Services.OrganizationService.InnerOrganizationService.UsingService(Func`2操作)
位于Microsoft.Xrm.Client.Services.OrganizationService.Create(实体)
在MyClientCode.cs中的MyClientCode()处:第100行
我猜发生这种情况是因为
UpdateFrobber(…)
使用从插件派生的IOOrganizationService实例,因此它进行的任何CRM服务调用都会与插件参与同一事务,如果这些“子”操作失败,则会导致整个事务回滚。这是正确的吗?有没有一种“安全”的方法可以忽略同步插件中“子”操作的错误?也许是一种实例化IorOrganizationService实例的方法,它不会重复使用插件的上下文


如果相关,我们将在本地运行CRM 2013。

当插件参与数据库事务时,您不能忽略子插件中未处理的异常


但是,当您的插件在部分受信任模式下运行时,您实际上可以创建自己的
OrganizationServiceProxy
实例,并使用该实例访问CRM。确保引用插件正在执行的服务器以避免“双跳”问题。

如果真的需要,我会创建一个带有ContinueOnError=true的ExecuteMultipleRequest,对于您的电子邮件,您可以只检查ExecuteMultipleResponse


但这看起来有点过头了。

如果在异步模式下运行,您可以捕获异常。捕获异常时,请确保验证您的模式

示例代码:

试试看
{
ExecuteTransactionResponse响应=
(ExecuteTransactionResponse)service.Execute(exMultReq);
}
捕获(例外情况除外)
{
错误=正确;
如果(context.Mode==0)//0同步,1异步。
抛出新的InvalidPlugineExecutionException(
$“执行多个事务
失败。\n{ex.Message}\n{innermessage},ex);
}
if(errored==true)
{
//做更多的事情来处理它,比如记录故障。

}
Caleb您确定此后不会执行插件吗?我的意思是,你的方法触发了另一个出错的插件,如果它是同步的,那么你正在寻找的插件就会失败。为了防止这种情况发生,您可以将子插件移动到后期异步,或者您可以管理子插件中的异常。我听说一个ExecuteMultipleRequest也将在事务之外执行,但我没有测试它…@Henk当您说要避免“双跳”问题时,您的意思是避免在与当前服务器/组织不同的服务器/组织上调用方法吗?有没有一种方法可以通过编程从插件的上下文中获取XRM连接字符串,这样我就不必在插件注册的不安全信息中提供它?当