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".

Другие вопросы по тегам