DataObject can't get httpcontext

18 posts, 0 answers
  1. Piyawadee
    Piyawadee avatar
    4 posts
    Member since:
    Oct 2016

    Posted 13 Mar 2017 Link to this post

         I have created Reporting Projects which are RestService, and ReportLibrary. These two projects will be integrated with another project. The problem is Reporting Project can't get httpcontext that send from another project. I tried to figure out the problem and i found that it was success to receive the httpcontext in RestService(as image Success001, Success002) but ReportLibrary cannot(as image Failed001, Failed002). You can see example images that attach with this post.

     

    Has anyone found this? or any suggestion?

    Thank you

     

  2. Stef
    Admin
    Stef avatar
    3610 posts

    Posted 13 Mar 2017 Link to this post

    Hello Warinthorn,

    Please check HttpContext.Current.User is not available in the data-retrieval method executed by an ObjectDataSource component.

    In general, we copy the current context on processing the report, but this does not include the whole object. The current context is available in the Reporting REST Service's methods, the report's constructor and events, but not in the process handling the data-retrieval via data source components.


    In order to provide you more accurate suggestions, please elaborate on the usage of the current context in the report.

    Regards,
    Stef
    Telerik by Progress
    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. Gregory Petrites
    Gregory Petrites avatar
    3 posts
    Member since:
    Jul 2005

    Posted 13 Mar 2017 in reply to Stef Link to this post

    You indicate that the current context is available in the reports constructor, but this does not appear to be consistently true.
    We have an application which uses javascript to add reports to the page.  When the report is opened, the report constructor is called (at least) three times.  The first two times HttpContext.Current.User has a value.  The third time, it does not.  I just tested the previous version and all three times, the HttpContext.Current.User had a value.

    From a security perspective, we need the report to be able to independently verify the user identity as opposed to receiving as a parameter. The way we solve this is by using Ninject DI to inject HttpContext.Current.User as an IPrincipal into all the different layers that need to know the user's identity. This also prevents the need from having to manually pass user name thru application layers that have no direct need for the identity.

    For the report data sources, we were able to make this work in version 10.2.16.1025 of Telerik Reporting by manually using DependencyResolver to instantiate the data sources in the report constructor.  (Technically, we use an extension method and reflection to minimize the coding impact for each report)

        var obj = DependencyResolver.Current.GetService((Type)objectDataSource.DataSource);
        objectDataSource.DataSource = obj;

    Additionally, we told Ninject to use a copy of the user identity instead of the real identity as this was sufficient for our needs and overcame an issue when the HttpContext User was disposed before the object data sources used it.

     

    Kernel.Bind<IPrincipal>()
        .ToMethod(x => new GenericPrincipal(new GenericIdentity(HttpContext.Current.User.Identity.Name), null))
        .InRequestScope();

     

    Unfortunately, something appears the have changed between our original version and version 11.0.17.222 such that the third call to constructor the report no longer has access to HttpContext.Current.User so we are no unable to upgrade without completely re-architecting how we pass user identity through the application layers.

  4. Gregory Petrites
    Gregory Petrites avatar
    3 posts
    Member since:
    Jul 2005

    Posted 14 Mar 2017 in reply to Gregory Petrites Link to this post

    I think I have a new hack/solution for getting the user identity into the object data source using dependency injection.  This solution actually resolves two separate issues, which in my particular case are intertwined as the first sets up the platform for resolving the second:
    • Using dependency injection in the object data source layer behind reports
    • Accessing the user identity in the object data source layer (by use of dependency injection)

    First the dependency injection...

    1. Create an extension method (and helper function) to manually instantiate objet data sources using DI:

    public static void InjectDependencies(this Telerik.Reporting.Report report)
    {
        // Inject dependencies on the report data source if necessary
        // There can be multiple data source in the report
        // Use reflection to find out all the data sources and inject dependencies
        BindingFlags bindFlags = BindingFlags.Instance
                                   | BindingFlags.Public
                                   | BindingFlags.NonPublic;
     
        Type reportType = report.GetType();
        FieldInfo[] fieldInfo = reportType.GetFields(bindFlags);
        foreach(var field in fieldInfo)
        {
            if(field.FieldType == typeof(ObjectDataSource))
            {
                (field.GetValue(report) as ObjectDataSource).InjectDependencies();
            }
        }
    }
     
    public static void InjectDependencies(this ObjectDataSource objectDataSource)
    {
        if (objectDataSource != null
            && objectDataSource.DataSource is Type)
        {
            var obj = DependencyResolver.Current.GetService((Type)objectDataSource.DataSource);
            objectDataSource.DataSource = obj;
        }
    }

     

    2. Call the extension method in the constructor for all reports.

    public partial class R0201 : Telerik.Reporting.Report
    {
        public R0201()
        {
            InitializeComponent();
            this.InjectDependencies();
        }
    }

     

    Now that DI is working, we can resolve the issue of getting the user identity using dependency, using:

    • A GenericPrinicpal when HttpContext.Current.User is available to handle situations in which the User object is disposed by ASP.NET before it is used.
    • A cookie to fill in when HttpContext.Current.User is not available (with some logic to try to protect against spoofing).

    1. First a method to generic an IPrincipal object that can be injected in the object data source layer (note that the function parameter only exists to make this method friendly to Ninject). This method also performs all cookie maintenance and is therefore standalone:

    private static IPrincipal GetIPrincipal(Ninject.Activation.IContext ctx)
    {
        var contextUserName = HttpContext.Current.User?.Identity?.Name;
        var cookieUserName = HttpContext.Current.Request.Cookies[USERNAME_COOKIENAME]?.Value;
     
        if (contextUserName != null)
        {
            if (cookieUserName != null && cookieUserName != contextUserName)
                throw new Exception("Username mismatch");
     
            HttpContext.Current.Response.Cookies.Add(new HttpCookie(USERNAME_COOKIENAME, contextUserName));
            return new GenericPrincipal(new GenericIdentity(contextUserName), null);
        }
        else if (cookieUserName != null)
        {
            return new GenericPrincipal(new GenericIdentity(cookieUserName), null);
        }
        throw new Exception("Can't determine user name");
    }

    2. Next, set up the injection (Ninject specific):

    Kernel.Bind<IPrincipal>()
        .ToMethod(GetIPrincipal)
        .InRequestScope();
  5. Stef
    Admin
    Stef avatar
    3610 posts

    Posted 16 Mar 2017 Link to this post

    Hi Gregory,

    Thank you for the provided information. We will appreciate it, if you have chance to submit it in a project as a Case Study.
    Beside the selected approach, you can use a custom resolver in which you can create an instance of your report via custom report constructor accepting the current context. The custom resolver will have to return an InstanceReportSource.


    About the reported problem, we can confirm the current context is lost on the third call to the Reporting REST Service's resolver. Also before and now in time, the current context is not available in events and data-retrieval methods executed by data source components (is not available during the report processing).
    The reason is that on requesting the document (GetDocument request to the service) we send the server-side ReportSource to an internal ReportProcessor, and the creation of the report and its processing happen in a separate context. Our developers will research how to copy the original context in the newly created context where the report is processed.

    Your Telerik points are updated to thank you for bringing the issue to our attention.

    Regards,
    Stef
    Telerik by Progress
    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
  6. Graham
    Graham avatar
    2 posts
    Member since:
    May 2015

    Posted 16 Jul 2017 in reply to Stef Link to this post

    Is there an ETA for when this will be fixed? This causing me grief as well.
  7. Stef
    Admin
    Stef avatar
    3610 posts

    Posted 17 Jul 2017 Link to this post

    Hello Graham,

    The fix is not scheduled for a release yet and there is no exact ETA. We will re-discuss the priority of the issue and I will post an update in this thread.


    In general, the changed behavior can be seen in versions newer than v10.2.16.1219.

    Please use the approach suggested by Gregory Petrites, or the approach based on Telerik Reporting - a custom resolver where you can instantiate the report and pass custom information like the current context in it.
    Thank you for your understanding.

    Regards,
    Stef
    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
  8. Stef
    Admin
    Stef avatar
    3610 posts

    Posted 18 Jul 2017 Link to this post

    Hi everyone,

    The impact of the changes which will follow is still evaluated and a fix can be expected at earliest for R3 2017 in the middle of September.

    Having the above into account, our recommendation is to switch to a custom resolver allowing you to pass the needed information in the report.
    Thank you for your understanding.

    Regards,
    Stef
    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
  9. Idol
    Idol avatar
    1 posts
    Member since:
    Nov 2017

    Posted 22 Dec 2017 in reply to Stef Link to this post

    Hi Stef,

    Is changes were made in R3 2017 or it`ll be implemented in next version?

  10. Katia
    Admin
    Katia avatar
    693 posts

    Posted 02 Jan 2018 Link to this post

    Hello Idol,

    The changes were introduced in R3 2017 release (11.2.17.913) - release notes.


    Regards,
    Katia
    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
  11. BVZ
    BVZ avatar
    5 posts
    Member since:
    Feb 2017

    Posted 22 May 2018 in reply to Katia Link to this post

    Could it be that this bug is again present in the current R2 2018 Release (2018.2.516.545) ?

    My HttpContext.Current is always null the third time the resolve method is being called.

  12. HMPSOLBB
    HMPSOLBB avatar
    24 posts
    Member since:
    Mar 2012

    Posted 24 May 2018 in reply to BVZ Link to this post

    BVZ said:

    Could it be that this bug is again present in the current R2 2018 Release (2018.2.516.545) ?

    My HttpContext.Current is always null the third time the resolve method is being called.

    We have the same problem

     

    @Telerik:

    Is there an ETA for when this will be fixed?

     

  13. Todor
    Admin
    Todor avatar
    384 posts

    Posted 24 May 2018 Link to this post

    Hi,

    Starting with Telerik Reporting R1 2018 SP3 (12.0.18.416) the System.Web.HttpContext.Current is NOT available in the report rendering thread. To access the current user context use the Telerik.Reporting.Processing.UserIdentity.Current static property.
    The purpose of this change is to allow the rendering engine to use a dedicated rendering thread queue with configurable count which will significantly improve product's performance.

    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
  14. Cory
    Cory avatar
    3 posts
    Member since:
    Aug 2011

    Posted 29 Jun 2018 in reply to Todor Link to this post

    I thought I would throw in a solution for our situation.  Accessing the UserIdentity didn't help, the Context was null there as well.  What we were after was a replacement for HttpContext.Current.Server.MapPath("~/")  and this did the trick.

     

    Replaced:

    appPath = HttpContext.Current.Server.MapPath("~/");

    with:

    appPath = System.Web.Hosting.HostingEnvironment.MapPath("~/");

     

  15. Todor
    Admin
    Todor avatar
    384 posts

    Posted 04 Jul 2018 Link to this post

    Hello Cory,

    The Context of UserIdentity should be created before using, if it is needed (i.e. to carry information from HttpContext to the report engine).
    You can save items from the HttpContext to the UserIdentity by overriding the GetUserIdentity() method in the ReportsController, and adding the needed items to the UserIdentity.Context property:

    protected override UserIdentity GetUserIdentity()
    {
        var identity = base.GetUserIdentity();
        identity.Context = new System.Collections.Concurrent.ConcurrentDictionary<string, object>();
        identity.Context["appPath"] = System.Web.HttpContext.Current.Server.MapPath("~/");
        // More user items can be added to identity.Context here
     
        return identity;
    }

    The appPath can then be taken as UserIdentity.Current.Context["appPath"], for example:

    var appPath = UserIdentity.Current.Context["appPath"];

    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
  16. Asif
    Asif avatar
    2 posts
    Member since:
    Jan 2016

    Posted 28 Jul 2018 in reply to Todor Link to this post

    Hello Todor,

    After Telerik Reporting R1 2018 SP3 (12.0.18.416) upgrade, I am not able to run two different REST Services one after other.

    Below are my two services. 

    REST Service 1

    =======================================================================

    static ReportsController()
            {
                
                var appPath = HttpContext.Current.Server.MapPath("~/");
                var reportsPath = Path.Combine(appPath, "Reports");

                var resolver = new ReportFileResolver(reportsPath)
                    .AddFallbackResolver(new ReportTypeResolver());

                configurationInstance = new ReportServiceConfiguration
                {
                    HostAppId = "Html5AppRep",
                    Storage = new Telerik.Reporting.Cache.MsSqlServerStorage("Data Source=tfssrv12\\dbtrideo;Failover Partner=824269-DB4;Initial Catalog=TrideoReports;Integrated Security=True;Connection Timeout=600"),
                    ReportResolver = resolver,
                    ClientSessionTimeout = 15,
                };
            }

    REST Service 2
    =======================================================================

     static ADHOCReportController()
            {
                //Setup the ReportServiceConfiguration
                configurationInstance = new ReportServiceConfiguration
                {
                    HostAppId = "Html5App",
                    Storage = new Telerik.Reporting.Cache.MsSqlServerStorage("Data Source=tfssrv12\\dbtrideo;Failover Partner=824269-DB4;Initial Catalog=TrideoNewReports;Integrated Security=True;Connection Timeout=600"),
                    ReportResolver = new MyResolver(),//resolver,
                    ClientSessionTimeout = 15,
                    
                };
            }

    =======================================================================

    These both REST Services are resides in a project and i was able to run both services at any time. 

    But After upgrade, After login in my application, First If i run the REST Service1 then i am not able to run Rest Service 2.

    Or After login, First if i run the REST Service2 then i am not able to run REST Service 1.

    Attached is a fiddler log in which the first report was successful, but the second report has stopped at "0 Pages loaded so far..." and its not delivering report. 

    What changes do i need to handle for both services according to new upgrade. I manage the same HostAppID name is also not solved this issue. 

    Please help

  17. Asif
    Asif avatar
    2 posts
    Member since:
    Jan 2016

    Posted 28 Jul 2018 in reply to Todor Link to this post

    Hello Todor ,

    After Telerik Reporting R1 2018 SP3 (12.0.18.416) upgrade, i am not able to execute 2 REST Services one after other. 

    These 2 REST Services are in single Project and after logged in in application only any one REST Service is delivering report.

    Below are 2 Services

    REST Service 1

    ====================================================================

     static ADHOCReportController()
            {
                //Setup the ReportServiceConfiguration
                configurationInstance = new ReportServiceConfiguration
                {
                    HostAppId = "Html5App",
                    Storage = new Telerik.Reporting.Cache.MsSqlServerStorage("Data Source=tfssrv12\\dbtrideo;Failover Partner=824269-DB4;Initial Catalog=TrideoNewReports;Integrated Security=True;Connection Timeout=600"),
                    ReportResolver = new MyResolver(),//resolver,
                    ClientSessionTimeout = 15,
                    
                };
            }

    REST Service 2

    =================================================================

    static ReportsController()
            {
                
                var appPath = HttpContext.Current.Server.MapPath("~/");
                var reportsPath = Path.Combine(appPath, "Reports");

                var resolver = new ReportFileResolver(reportsPath)
                    .AddFallbackResolver(new ReportTypeResolver());

                configurationInstance = new ReportServiceConfiguration
                {
                    HostAppId = "Html5AppRep",
                    Storage = new Telerik.Reporting.Cache.MsSqlServerStorage("Data Source=tfssrv12\\dbtrideo;Failover Partner=824269-DB4;Initial Catalog=TrideoReports;Integrated Security=True;Connection Timeout=600"),
                    ReportResolver = resolver,
                    ClientSessionTimeout = 15,
                };
            }

    I tried with Same HostAppID for both services also but did not worked. After  Telerik Reporting R1 2018 SP3 (12.0.18.416) upgrade what are code changes do we need to handle to execute both services simultaneously. 

    After logged in in application, he first service report execution successfully, and when run the second rest service the report is stopped at "0 pages loaded so far..." and report not delivered.

     

    Please help

  18. Todor
    Admin
    Todor avatar
    384 posts

    Posted 01 Aug 2018 Link to this post

    Hello Asif,

    I noticed that you have already opened a support ticket (#1177104) where you have asked similar questions. I suggest to continue the discussion there as it is not directly related to the topic of this forum thread.

    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
Back to Top