0

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();
                        }
                    }
                }

            }
        }
4

1 に答える 1

0

ユーザー フィールドにポイントを与える必要がある場合は、ObjectEvents.Update.Before を使用して、フィールドが空でないことを確認し、ポイントを割り当てることができます。しかし、コードからわかるように、マクロ式よりも複雑なものが必要です。そこで、いくつか提案があります。

1) ObjectEvents.Update.After の代わりに ObjectEvents.Update.Before を使用することをお勧めします。理想的には、追加の値を設定し、すべてが 1 回の更新中に設定されます。

2) 必要なクラス名だけを見る

3) info.Update() よりも Provider.SetInfo メソッドを常に優先します。ユーザー設定の場合は、ユーザー情報全体を設定するのが最善です。したがって、UserInfoProvider.SetUserInfo. プロバイダー メソッドは、いくつかの重要なロジックを追加する場合があります。

4) コードは、ユーザーが更新されるたびにポイントを追加するようです

5) まだループに陥っている場合は、何らかの方法でフラグを立てて、コードの一部を再度実行しないようにする必要があります。最善の方法は、RequestStockHelper クラスを使用することです。"PointsProcessed" のような特定の名前の bool 値を追加します。

于 2013-12-31T08:50:59.467 に答える