Kentico Global Events (ObjectEvents) вызывает цикл
Я использую ObjectEvents для предоставления ActivityPoints текущему пользователю на основе полей, заполненных пользователем. Теперь, например, если пользователь зарегистрируется и заполнит FirstName, я дам 10 баллов пользователю. Проблема в том, что я обрабатываю ObjectEvents.Update.After и внутри него я обновляю userSettings.Это вызывает неограниченный цикл и приложение перестает работать. есть ли работа вокруг?
это блок кода:
var className = e.Object.TypeInfo.ObjectClassName;
DataClassInfo dci = DataClassInfoProvider.GetDataClass(className);
if (dci != null)
{
var fi = new FormInfo(dci.ClassFormDefinition);
if (fi != null)
{
var stopProccess = true;
var fields = new List<FormFieldInfo>();
foreach (var changedColumn in e.Object.ChangedColumns())
{
var field = fi.GetFormField(changedColumn);
var activityPointMacro = ValidationHelper.GetString(field.Settings["ActivityPointMacro"], "");
if (!string.IsNullOrEmpty(activityPointMacro))
{
fields.Add(field);
stopProccess = false;
}
}
if (!stopProccess)
{
var contextResolver = CMSContext.CurrentResolver.CreateContextChild();
foreach (FormCategoryInfo info in fi.ItemsList.OfType<FormCategoryInfo>())
{
contextResolver.SetNamedSourceData(info.CategoryName, info);
}
EditingFormControl data = new EditingFormControl();
foreach (FormFieldInfo info2 in fi.ItemsList.OfType<FormFieldInfo>())
{
contextResolver.SetNamedSourceData(info2.Name, data);
}
foreach (var field in fields)
{
{
var activityPointMacro = ValidationHelper.GetString(field.Settings["ActivityPointMacro"], "");
var activityPoint =
ValidationHelper.GetInteger(contextResolver.ResolveMacros(activityPointMacro), 0);
CMSContext.CurrentUser.UserSettings.UserActivityPoints += activityPoint;
CMSContext.CurrentUser.UserSettings.Update();
}
}
}
}
}
1 ответ
Если вам просто нужно дать баллы за пользовательские поля, то вы можете просто использовать ObjectEvents.Update.Before, проверить поля не являются пустыми и назначить точки. Но я могу видеть из кода, что вы хотите иметь что-то более сложное, чем выражения макросов. Итак, у меня есть несколько предложений для вас.
1) ObjectEvents.Update.Before вместо ObjectEvents.Update.After все еще может быть хорошей идеей. В идеале вы устанавливаете свои дополнительные значения, и все устанавливается в течение одного обновления.
2) Смотреть только названия классов, которые вам нужны
3) Всегда предпочитайте методы Provider.SetInfo, а не info.Update(). В случае пользовательских настроек лучше всего устанавливать всю информацию о пользователе, поэтому UserInfoProvider.SetUserInfo. Методы провайдера могут добавить некоторую дополнительную важную логику.
4) код кажется, что он будет добавлять точки с каждым обновлением пользователя
5) если вы все еще работаете в цикле, вам нужно как-то пометить, что некоторая часть кода не должна выполняться снова. Лучший способ - использовать класс RequestStockHelper - добавить значение bool с определенным именем, например "PointsProcessed".