This is a migrated thread and some comments may be shown as answers.

DataObject can't get httpcontext

17 Answers 541 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Atlas
Top achievements
Rank 1
Atlas asked on 13 Mar 2017, 11:10 AM

     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

 

17 Answers, 1 is accepted

Sort by
0
Stef
Telerik team
answered on 13 Mar 2017, 01:22 PM
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
0
Gregory Petrites
Top achievements
Rank 1
answered on 14 Mar 2017, 12:02 AM

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.

0
Gregory Petrites
Top achievements
Rank 1
answered on 14 Mar 2017, 01:47 PM
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();
0
Stef
Telerik team
answered on 16 Mar 2017, 02:16 PM
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
0
Graham
Top achievements
Rank 1
answered on 16 Jul 2017, 05:59 PM
Is there an ETA for when this will be fixed? This causing me grief as well.
0
Stef
Telerik team
answered on 17 Jul 2017, 12:32 PM
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
0
Stef
Telerik team
answered on 18 Jul 2017, 08:22 AM
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
0
Idol
Top achievements
Rank 1
answered on 22 Dec 2017, 10:58 AM

Hi Stef,

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

0
Katia
Telerik team
answered on 02 Jan 2018, 07:18 AM
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
0
BVZ
Top achievements
Rank 1
answered on 22 May 2018, 08:05 AM

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.

0
HMPSOLBB
Top achievements
Rank 1
answered on 24 May 2018, 01:04 PM
[quote]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.

[/quote]

We have the same problem

 

@Telerik:

Is there an ETA for when this will be fixed?

 

0
Todor
Telerik team
answered on 24 May 2018, 03:29 PM
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
0
Cory
Top achievements
Rank 1
answered on 29 Jun 2018, 05:05 PM

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("~/");

 

0
Todor
Telerik team
answered on 04 Jul 2018, 11:30 AM
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
0
Asif
Top achievements
Rank 1
answered on 28 Jul 2018, 10:46 AM

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

0
Asif
Top achievements
Rank 1
answered on 28 Jul 2018, 10:55 AM

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

0
Todor
Telerik team
answered on 01 Aug 2018, 02:39 PM
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
Tags
General Discussions
Asked by
Atlas
Top achievements
Rank 1
Answers by
Stef
Telerik team
Gregory Petrites
Top achievements
Rank 1
Graham
Top achievements
Rank 1
Idol
Top achievements
Rank 1
Katia
Telerik team
BVZ
Top achievements
Rank 1
HMPSOLBB
Top achievements
Rank 1
Todor
Telerik team
Cory
Top achievements
Rank 1
Asif
Top achievements
Rank 1
Share this question
or