Dynamic Localization issue

3 posts, 1 answers
  1. Blong
    Blong avatar
    2 posts
    Member since:
    Mar 2016

    Posted 01 Aug 2018 Link to this post

    I have an MVC application that needs to allow dynamically changing connection strings and localization. The issue is that after I open up the first report instance, I am still getting the same report even after changing connection strings or the localization.  Here is my code:

     

    private ReportServiceConfiguration GetReportServiceConfiguration()
        {
          var userId = _httpContext.User.FindFirst(ClaimTypes.NameIdentifier);
          var connectionString = _configuration.GetConnectionString("db");
          var locale = "en";
     
          if (userId != null)
          {
            var user = _userManager.FindByIdAsync(userId.Value).Result;
            var tenantClaim = (_userManager.GetClaimsAsync(user).Result).SingleOrDefault(c => c.Type == "UserTenant");
            var localeClaim = (_userManager.GetClaimsAsync(user).Result).SingleOrDefault(c => c.Type == "UserLocale");
     
            if (tenantClaim != null)
            {
              connectionString = connectionString.Replace("=db", "=" + tenantClaim.Value);
            }
            if(localeClaim != null)
            {
              locale = localeClaim.Value;
            }
          }
     
          var resolver = new NexcorTypeResolver(connectionString, locale);
     
          return new ReportServiceConfiguration
          {
            HostAppId = "Test",
            Storage = new FileStorage(this.reportsPath),
            ReportResolver = resolver,
            ReportSharingTimeout = 0,
            ClientSessionTimeout = 1
          };
        }
      }

     

    public class NexcorTypeResolver : IReportResolver
      {
        public string _connectionString;
        public string _locale;
        public NexcorTypeResolver(string connectionString, string locale)
        {
          _connectionString = connectionString;
          _locale = locale;
        }
        public ReportSource Resolve(string report)
        {
          var cultureInfo = new System.Globalization.CultureInfo(_locale);
          System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
          System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
          var connectionStringHandler = new ReportConnectionStringManager(_connectionString);
          var sourceReportSource = new InstanceReportSource { ReportDocument = new Worksheet() };
          var reportSource = connectionStringHandler.UpdateReportSource(sourceReportSource);

          return reportSource;
        }
      }

  2. Answer
    Todor
    Admin
    Todor avatar
    333 posts

    Posted 03 Aug 2018 Link to this post

    Hi Blong,

    We have responded to your queries on the same issue in the support ticket 1180382 you opened on the same case. I will post the answer briefly also here for the benefit of our community:

    It seems that you use the HttpContext to pass the culture information.
    Starting with Telerik Reporting R1 2018 SP3 (12.0.18.416) the System.Web.HttpContext.Current is not available in the report rendering thread.
    Please, check the How to use information form HttpContext in Custom Report Resolver KB article for additional information and an example, and test to pass the culture information using the newly introduced UserIdentity.Context property.

    Regards,
    Todor
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Blong
    Blong avatar
    2 posts
    Member since:
    Mar 2016

    Posted 31 Aug 2018 Link to this post

    Thanks for the response, I have gotten the functionality working and wanted to share the solution with everyone. Following Todor's suggestion, I created the override method for GetUserIdentity() and moved moved all my claim code into there. From there I access the UserIdentity.Current.Context in the resolver to gain access to those particular values.

    private ReportServiceConfiguration GetReportServiceConfiguration()
        {
          var resolver = new NexcorTypeResolver();
     
          return new ReportServiceConfiguration
          {
            HostAppId = "Test",
            Storage = new FileStorage(),
            ReportResolver = resolver,
            ReportSharingTimeout = 1,
            ClientSessionTimeout = 1
          };
        }
     
        protected override UserIdentity GetUserIdentity()
        {
          var identity = base.GetUserIdentity();
          identity.Context = new System.Collections.Concurrent.ConcurrentDictionary<string, object>();
     
          var userId = _httpContext.User.FindFirst(ClaimTypes.NameIdentifier);
          var connectionString = _configuration.GetConnectionString("db");
          var locale = "en";
     
          if (userId != null)
          {
            var user = _userManager.FindByIdAsync(userId.Value).Result;
            var tenantClaim = (_userManager.GetClaimsAsync(user).Result).SingleOrDefault(c => c.Type == "UserTenant");
            var localeClaim = (_userManager.GetClaimsAsync(user).Result).SingleOrDefault(c => c.Type == "UserLocale");
     
            if (tenantClaim != null)
            {
              connectionString = connectionString.Replace("=db", "=" + tenantClaim.Value);
            }
            if (localeClaim != null)
            {
              locale = localeClaim.Value;
            }
          }
     
          identity.Context["Locale"] = locale;
          identity.Context["ConnectionString"] = connectionString;
     
          return identity;
        }
      }
     
      public class NexcorTypeResolver : IReportResolver
      {
        public NexcorTypeResolver()
        {
        }
     
        public ReportSource Resolve(string report)
        {
          var locale = UserIdentity.Current.Context["Locale"];
          var connectionString = UserIdentity.Current.Context["ConnectionString"];
          var cultureInfo = new System.Globalization.CultureInfo(locale.ToString());
          System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
          System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
          var connectionStringHandler = new ReportConnectionStringManager(connectionString.ToString());
          var sourceReportSource = new InstanceReportSource { ReportDocument = new Worksheet() };
          var reportSource = connectionStringHandler.UpdateReportSource(sourceReportSource);
     
          return reportSource;
        }
      }

     

Back to Top