Developer forum

Forum » Development » User Macro not working after recycle

User Macro not working after recycle

Adrian Ursu Dynamicweb Employee
Adrian Ursu
Reply

Hi guys,

I have a project where we have developed a UserMacro that is supposed to return a comma-separated list of ProductNumbers based on some information in a custom table. Nothing fancy so far.

Setting up the Macro in the query worked pretty well, and we got the desired outcome.

The problem comes after the application recycles. If the application recycles the query expression is not applied unless I run the index again.

It is a weird behavior since the query and the index should not be connected but it is happening nevertheless.

I have checked the value returned by the Macro and it is identical both before and after the recycle.

Here is the code that we have used:

public class DfFilterProductsMacro : Macro
    {
        protected static readonly Dictionary<string, Func<object>> SupportedActionsInternal = new Dictionary<string, Func<object>>() { { "BlockedItemsExtended2", () => GetAllowedProductsByCustomerNumber() } };
        protected static readonly object LockObject = new object();

        public override object Evaluate(string action)
        {
            // Prepare return value          
            lock (LockObject)
            {
                object value = null;

                try
                {
                    // Make sure action is supported
                    if (SupportedActionsInternal.ContainsKey(action))
                    {
                        // Get value from action
                        value = SupportedActionsInternal[action]();
                    }

                    if (value != null)
                    {
                        IEnumerable<string> arr = (IEnumerable<string>)value;

                        LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Warn($"action:{action} ; ids evaluateResult:{string.Join(",", arr)}");
                    }
                    else
                    {
                        LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Warn($"action:{action} ; value is null");
                    }
                }
                catch (Exception ex)
                {
                    // Maybe log this?

                    LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Error($"Evaluate error :{ex.Message} action:{action}");
                }

                // Return the value if one was found, otherwise Nothing
                return value;
            }
        }

        public override string Name
        {
            get
            {
                return "Df.UserManagement.Context";
            }
        }

        public override IEnumerable<string> SupportedActions
        {
            get
            {
                IEnumerable<string> result;
                lock (LockObject)
                    result = SupportedActionsInternal.Keys.ToList();
                return result;
            }
        }

        protected static string GetCacheKey(string macroKey, string userId, string listId = "")
        {
            return $"{macroKey}|{userId}|{listId}";
        }

        public static object GetAllowedProductsByCustomerNumber()//gets blocked product numbers
        {
            string cacheKey = "DfUserMacro.GetAllowedProductsByCustomerNumber";

            var user = User.GetCurrentExtranetUser();

            var ids = new List<string>();

            if (user == null)
            {
                LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Warn($"no backend user");

                try
                {
                    var encryptedUserid = Dynamicweb.Context.Current.Request.Params["UserId"];
                    var userid = Dynamicweb.Security.SystemTools.Crypto.Decrypt(encryptedUserid);

                    LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Warn($"encryptedUserid:{encryptedUserid};userid:{userid}");

                    user = User.GetUserByID(Converter.ToInt32(userid));
                }
                catch (Exception e)
                {
                    LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Error(e.Message);
                }
            }

            if (user == null)
            {
                LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Warn($"user is still null return");

                return ids.ToArray();
            }

            LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Warn($"user found :{user.ID};user.CustomerNumber;{user.CustomerNumber}");

            cacheKey = GetCacheKey(cacheKey, user.ID.ToString());
            object cache = null;
            if (Dynamicweb.Caching.Cache.Current.TryGet(cacheKey, out cache))
            {
                return cache;
            }

            try
            {
                string sql = @" SELECT ITEMNUMBER FROM _CustomerItemBlocked Where CUSTOMERNUMBER=@CUSTOMERNUMBER ";

                using (var conn = Database.CreateConnection())
                {
                    using (var cmd = new SqlCommand(sql, (SqlConnection)conn))
                    {
                        cmd.Parameters.Add("@CUSTOMERNUMBER
", SqlDbType.NVarChar).Value = user.CustomerNumber;

                        cmd.CommandType = System.Data.CommandType.Text;

                        DataSet ds = new DataSet();
                        SqlDataAdapter da = new SqlDataAdapter(cmd);
                        da.Fill(ds, "Result");
                        foreach (DataRow pRow in ds.Tables["Result"].Rows)
                        {
                            string itemNr = pRow["ITEMNUMBER"].ToString();

                            ids.Add(itemNr);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Error(e.Message);
            }

            Dynamicweb.Caching.Cache.Current.Set(cacheKey, ids);

            //LogManager.System.GetLogger(LogCategory.Health, "DfIndexFilterProductsByCustomerNumber").Warn($"ids:{string.Join(",",ids)}");

            return ids.ToArray();
        }

    }

Can anybody tell me what is wrong with our code?

Thank you,

Adrian 


Replies

 
Adrian Ursu Dynamicweb Employee
Adrian Ursu
Reply

Anybody?

This is a bit critical because this logic is supposed to hide products on a production website.

Thank you,
Adrian

 
Nicolai Pedersen
Reply

Hi Adrian

We are pretty sure it is not related to the index - if you can record that - that would be nice.

We are looking into your code - we cannot see what the error is. We think that somehow the macro returns null, probably because of the cache being loaded with empty content initially, which would cause the expression to be ignored.

Will get back.

 
Adrian Ursu Dynamicweb Employee
Adrian Ursu
Reply

Hi Nicolai,

Thank you,
Adrian

 
Adrian Ursu Dynamicweb Employee
Adrian Ursu
Reply

Hi Nicolai,

Apparently, the problem is in the Query, not in the macro.

Initially, I was using  ProductNumber (string) - In - ExcludedProducts(string[])

This rule, somehow, worked immediately after configuration but did not work after the recycling.

I have created a new field in the index ProductNumberArray (string[])  and defined an expression with "Match Any" instead of "In".

And this time it seems to work even after recycle.

I am not sure why the "In" expression does not work anymore after recycling but this is what I have found in our tests. I hope it helps.

Thank you,

Adrian

 

You must be logged in to post in the forum