在表单上同时进行 2 个验证 运行 时出错
Error when have 2 validation running together on form
我的实体信用额度有 3 个字段,分别是信用评级、信用额度和配置,配置是一个查找字段,信用额度字段是货币,信用评级是选项集(A、B、 C)。所以当更新时它会验证 2 次,首先是信用评级不能与字段配置已经具有的信用评级相同
示例:我的预信用评级是 B,我的配置已经有 2 个信用额度,即 A 和 B,当我将信用评级更新为 A 时,它应该是一个错误,因为配置不能有 2 个相同的信用评级。
第二次验证是在更新字段信用额度时,所以当前信用额度不能超过原像信用额度字段,我的原像信用额度是 500 美元,当我尝试更新到 550 美元时会显示错误消息。
所以我创建了 2 个插件来验证这两个条件,并且我的事件管道执行阶段都设置为 PreOperation。
,这里是信用评级验证
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using TrainingConfiguration.Plugins.Model;
namespace TrainingConfiguration.Plugins
{
public class CreditRatingUpdateValidation : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
Entity entity = (Entity)context.InputParameters["Target"];
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = (IOrganizationService)serviceFactory.CreateOrganizationService(context.UserId);
if (entity.LogicalName.Contains("ita_creditlimit"))
{
Entity preImage = (Entity)context.PreEntityImages["CreditImage"];
EntityReference configuration = (EntityReference)(preImage.Attributes["ita_configuration"]);
string configurationId = configuration.Id.ToString();
string fetchXml = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='ita_creditlimit'>
<attribute name='ita_creditlimitid' />
<attribute name='ita_name' />
<attribute name='ita_creditrating' />
<attribute name='ita_configuration' />
<order attribute='ita_name' descending='false' />
<filter type='and'>
<condition attribute='ita_configuration' operator='eq' value=""{0}"" />
</filter>
</entity>
</fetch>";
fetchXml = string.Format(fetchXml, configurationId);
var qe = new FetchExpression(fetchXml);
var result = service.RetrieveMultiple(qe);
var preRating = ((OptionSetValue)preImage.Attributes["ita_creditrating"]).Value;
var postRating = ((OptionSetValue)entity.Attributes["ita_creditrating"]).Value;
if (result.Entities.Count > 0)
{
List<String> listCreditRating = new List<string>();
for (int i = 0; i < result.Entities.Count; i++)
{
string creditRating = ((OptionSetValue)result.Entities[i].Attributes["ita_creditrating"]).Value.ToString();
listCreditRating.Add(creditRating);
}
if (postRating.ToString() != preRating.ToString())
{
bool alreadyExist = listCreditRating.Contains(postRating.ToString());
if (alreadyExist == true)
{
throw new InvalidPluginExecutionException("Can't have 2 same rating");
}
}
}
}
}
}
}
此处用于信用额度验证
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using TrainingConfiguration.Plugins.Model;
namespace TrainingConfiguration.Plugins
{
public class CreditUpdateValidation : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
Entity entity = (Entity)context.InputParameters["Target"];
if (entity.LogicalName.Equals("ita_creditlimit"))
{
decimal parseInt1 = 0;
decimal parseInt2 = 0;
Entity preImage = (Entity)context.PreEntityImages["CreditImage"];
if (context.PreEntityImages.Contains("CreditImage"))
{
Money preValue = (Money)preImage.Attributes["ita_creditlimit"];
parseInt1 = preValue.Value;
}
Money postValue = (Money)entity.Attributes["ita_creditlimit"];
parseInt2 = postValue.Value;
if (parseInt2 > parseInt1)
{
throw new InvalidPluginExecutionException("Can't Exceed the credit limit");
}
}
}
}
}
这两个插件一开始都工作正常。在我尝试 运行 在一起之前,我不知道为什么当我尝试
运行 放在一起会有奇怪的异常,有时候会说属性ita_rating key not
找到或 ita_creditlimit 未找到,即使我已经在插件注册中将其添加到我的过滤属性中
我已经尝试解决这个问题一天了,但我仍然不知道为什么会发生这些奇怪的行为
因为当我试图禁用其中一个插件时,另一个插件会起作用,任何人都可以提供一些启发
这是什么原因?这是来自我的代码还是其他?我已经尝试使用 try 和 catch,这是我遇到的异常
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at TrainingConfiguration.Plugins.CreditUpdateValidation.Execute(IServiceProvider serviceProvider)
我想我已经知道这里出了什么问题,所以 Money postValue = (Money)entity.Attributes["ita_creditlimit"];
或 var value1 = (OptionSetValue)entity.Attributes["ita_creditrating"];
只有在值发生变化时才具有属性。例如,当我的信用额度是 500 美元时,我只是把它留在那里而不更新我的信用额度,这就是错误出现的时候,所以我用 try and catch 修复它,当它出现错误时,我将使用 PreImage 作为我的信用额度。
我的实体信用额度有 3 个字段,分别是信用评级、信用额度和配置,配置是一个查找字段,信用额度字段是货币,信用评级是选项集(A、B、 C)。所以当更新时它会验证 2 次,首先是信用评级不能与字段配置已经具有的信用评级相同
示例:我的预信用评级是 B,我的配置已经有 2 个信用额度,即 A 和 B,当我将信用评级更新为 A 时,它应该是一个错误,因为配置不能有 2 个相同的信用评级。
第二次验证是在更新字段信用额度时,所以当前信用额度不能超过原像信用额度字段,我的原像信用额度是 500 美元,当我尝试更新到 550 美元时会显示错误消息。
所以我创建了 2 个插件来验证这两个条件,并且我的事件管道执行阶段都设置为 PreOperation。
,这里是信用评级验证
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using TrainingConfiguration.Plugins.Model;
namespace TrainingConfiguration.Plugins
{
public class CreditRatingUpdateValidation : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
Entity entity = (Entity)context.InputParameters["Target"];
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = (IOrganizationService)serviceFactory.CreateOrganizationService(context.UserId);
if (entity.LogicalName.Contains("ita_creditlimit"))
{
Entity preImage = (Entity)context.PreEntityImages["CreditImage"];
EntityReference configuration = (EntityReference)(preImage.Attributes["ita_configuration"]);
string configurationId = configuration.Id.ToString();
string fetchXml = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='ita_creditlimit'>
<attribute name='ita_creditlimitid' />
<attribute name='ita_name' />
<attribute name='ita_creditrating' />
<attribute name='ita_configuration' />
<order attribute='ita_name' descending='false' />
<filter type='and'>
<condition attribute='ita_configuration' operator='eq' value=""{0}"" />
</filter>
</entity>
</fetch>";
fetchXml = string.Format(fetchXml, configurationId);
var qe = new FetchExpression(fetchXml);
var result = service.RetrieveMultiple(qe);
var preRating = ((OptionSetValue)preImage.Attributes["ita_creditrating"]).Value;
var postRating = ((OptionSetValue)entity.Attributes["ita_creditrating"]).Value;
if (result.Entities.Count > 0)
{
List<String> listCreditRating = new List<string>();
for (int i = 0; i < result.Entities.Count; i++)
{
string creditRating = ((OptionSetValue)result.Entities[i].Attributes["ita_creditrating"]).Value.ToString();
listCreditRating.Add(creditRating);
}
if (postRating.ToString() != preRating.ToString())
{
bool alreadyExist = listCreditRating.Contains(postRating.ToString());
if (alreadyExist == true)
{
throw new InvalidPluginExecutionException("Can't have 2 same rating");
}
}
}
}
}
}
}
此处用于信用额度验证
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using TrainingConfiguration.Plugins.Model;
namespace TrainingConfiguration.Plugins
{
public class CreditUpdateValidation : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
Entity entity = (Entity)context.InputParameters["Target"];
if (entity.LogicalName.Equals("ita_creditlimit"))
{
decimal parseInt1 = 0;
decimal parseInt2 = 0;
Entity preImage = (Entity)context.PreEntityImages["CreditImage"];
if (context.PreEntityImages.Contains("CreditImage"))
{
Money preValue = (Money)preImage.Attributes["ita_creditlimit"];
parseInt1 = preValue.Value;
}
Money postValue = (Money)entity.Attributes["ita_creditlimit"];
parseInt2 = postValue.Value;
if (parseInt2 > parseInt1)
{
throw new InvalidPluginExecutionException("Can't Exceed the credit limit");
}
}
}
}
}
这两个插件一开始都工作正常。在我尝试 运行 在一起之前,我不知道为什么当我尝试 运行 放在一起会有奇怪的异常,有时候会说属性ita_rating key not 找到或 ita_creditlimit 未找到,即使我已经在插件注册中将其添加到我的过滤属性中 我已经尝试解决这个问题一天了,但我仍然不知道为什么会发生这些奇怪的行为 因为当我试图禁用其中一个插件时,另一个插件会起作用,任何人都可以提供一些启发 这是什么原因?这是来自我的代码还是其他?我已经尝试使用 try 和 catch,这是我遇到的异常
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at TrainingConfiguration.Plugins.CreditUpdateValidation.Execute(IServiceProvider serviceProvider)
我想我已经知道这里出了什么问题,所以 Money postValue = (Money)entity.Attributes["ita_creditlimit"];
或 var value1 = (OptionSetValue)entity.Attributes["ita_creditrating"];
只有在值发生变化时才具有属性。例如,当我的信用额度是 500 美元时,我只是把它留在那里而不更新我的信用额度,这就是错误出现的时候,所以我用 try and catch 修复它,当它出现错误时,我将使用 PreImage 作为我的信用额度。