【问题标题】:Sitecore.Analytics.Tracker.Current is null when invoked through a pipeline通过管道调用时,Sitecore.Analytics.Tracker.Current 为 null
【发布时间】:2018-04-03 11:41:39
【问题描述】:

我需要根据用户尝试访问的国家/地区位置进行重定向。例如,当用户尝试从中国访问http://www.example.com/ 时,我的站点应为http://www.example.com/zh。我在管道过程中使用 sitecore 跟踪器进行检查,以使用以下方法获取国家代码。

public void Process(HttpRequestArgs args)
    {
        Assert.ArgumentNotNull(args, "args");

        if (HttpContext.Current == null
          || Context.Site == null
            ////TODO:       || Sitecore.Context.PageMode...
          || Context.Database == null || Context.Site.Name == "shell" || !this._sites.Contains(Context.Site.Name))
        {
            return;
        }

        // contains path including language and query string
        // (not anchor name), but not hostname.
        // We can use this to add the language back into the path.
        string rawPath = Sitecore.Context.RawUrl;

        if (!rawPath.StartsWith("/sitecore") && !rawPath.StartsWith("/" + Sitecore.Context.Language.Name + "/") && !rawPath.StartsWith("/" + Sitecore.Context.Language.Name) && !rawPath.StartsWith("/default.aspx"))
        {
            string langCode = "";

            if(!string.IsNullOrEmpty(GeoIPUtils.GetUserGeoIP()))
            {
                try
                {
                    string country = GeoIPUtils.GetUserGeoIP();;
                    if (country.Trim().ToUpper() == "China".ToUpper())
                        langCode = "zh";
                    else if (country.Trim().ToUpper() == "Japan".ToUpper())
                        langCode = "jp";
                    else if (country.Trim().ToUpper() == "Thailand".ToUpper())
                        langCode = "th";
                    else
                        langCode = "en";

                }
                catch(Exception)
                {
                    langCode = "en";
                }
            }
            else
            {

                langCode = HttpContext.Current.Request.Cookies["avc#lang"].Value.ToString();
            }

            if (!string.IsNullOrEmpty(langCode))
            {
                Language language = null;
                if (Language.TryParse(langCode, out language))
                {
                    //then try to get the language item id from the language or two letter iso code             
                    ID langID = LanguageManager.GetLanguageItemId(language, Sitecore.Context.Database);
                    if (!ID.IsNullOrEmpty(langID))
                    {
                        //sometimes the language found is slightly different than official language item used in SC                 
                        language = LanguageManager.GetLanguage(language.CultureInfo.TwoLetterISOLanguageName);

                        if (Context.Item != null)
                        {
                            List<string> availableLangs = LanguagesWithContent(Context.Item);
                            if (availableLangs != null && availableLangs.Count > 0 && !availableLangs.Contains(language.CultureInfo.TwoLetterISOLanguageName.ToString()))
                            {
                                langCode = availableLangs.FirstOrDefault().ToString();
                            }
                        }
                        else
                        {
                            langCode = "en";
                        }
                    }
                    else
                    {
                        langCode = "en";
                    }
                }
            }

            HttpContext.Current.Response.RedirectPermanent("/" + (String.IsNullOrEmpty(langCode) ? Sitecore.Context.Language.Name : langCode) + rawPath);

        }
    }

下面是GetUserGeoIP函数

public static string GetUserGeoIP()
    {
        string countryCode = "";
        try
        {
            countryCode = Sitecore.Analytics.Tracker.Current.Interaction.GeoData.Country;
        }
        catch(Exception ex)
        {
            Log.Error("GetUserGeoIP Error: " + ex.Message + " Source: " + ex.Source + " Stack Trace :" + ex.StackTrace + " Inner Ex : " + ex.InnerException, ex);
            countryCode = "GB";

        }

        if (!string.IsNullOrEmpty(countryCode))
        {
            var countryItem = ISO3166.FromAlpha2(countryCode);
            if (countryItem != null)
                return countryItem.Name;
        }

        return "Other";
    }

但我遇到了以下异常

7904 10:43:25 ERROR Cannot create tracker.
Exception: System.InvalidOperationException
Message: session is not initialized
Source: Sitecore.Analytics
   at Sitecore.Analytics.Data.HttpSessionContextManager.GetSession()
   at Sitecore.Analytics.Pipelines.EnsureSessionContext.EnsureContext.Process(InitializeTrackerArgs args)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Analytics.DefaultTracker.EnsureSessionContext()
   at Sitecore.Analytics.Pipelines.CreateTracker.GetTracker.Process(CreateTrackerArgs args)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Analytics.Tracker.Initialize()

注意:API 中使用了相同的 GetUserGeoIP 方法来获取正确的 countryName。我正在使用 Sitecore.NET 8.0 (rev. 151127) 版本

对此高度赞赏的任何帮助

【问题讨论】:

标签: sitecore sitecore8 sitecore-analytics


【解决方案1】:

您的处理器可能过早进入管道。您可以在此处找到请求管道的概述:http://sitecoreskills.blogspot.be/2015/02/a-sitecore-8-request-from-beginning-to.html

您应该在跟踪器初始化并获取地理数据后放置您的处理器。不久前我做了类似的事情,并将我的处理器放在startAnalytics 管道中。

获取地理数据是异步的,因此在第一个请求管道中执行此操作时可能(将会)出现问题。阅读此article 以通过调用UpdateGeoIpData 来解决该问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    相关资源
    最近更新 更多