Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RS 2005 ReportExecutionService ToggleItem method problem

485 views
Skip to first unread message

InvalidLastName

unread,
Jun 13, 2006, 7:20:52 PM6/13/06
to
(Sorry, this is a re-post via fixed no-spam email alias with my subscription)
Hi,
We are building a custom report viewer for our web application for rendering reports by calling reporting services web services (SOAP over HTTP).
The custom report viewer also perform text replacement to replace any reference pointing to report server in the output from Render method so we don't have to make the report server middle-tier public accessible (As my understanding is built-in report viewer, Microsoft.Reporting.WebForms.ReportViewer, still requires the report server be accessible by clients for images, drilldown, drill-through links)
 
 
The problem we currently encounter is the ReportExecutionService.ToggleItem method only toggle items after the first Render
 
Here is our scenario:
 
Request 1:
Build custom RDL
Load RDL by calling ReportExecutionService.LoadReportDefinition( ... )
Save the execution ID for later requests
Call Render method
Perform text replacement to replace all the report server references with our custom link, which will intercept the requests to report server middle-tier
return the result to client 
 
Request 2 (user clicks on the drilldown link) :
retrieve the execution ID from the first request
get toggle item id from request
call ReportExecutionService.ToggleItem( ... ), the method returns true, which means the item is found
Call Render method
Perform text replacement to replace all the report server references with our custom link, which will intercept the requests to report server middle-tier
return the result to client  
(So far everything works fine)
 
Request 3 (user clicks on another drilldown link) :
retrieve the execution ID from the first request
get toggle item id from request (different to the request 2)
call ReportExecutionService.ToggleItem( ... ), the method returns true, which means the item is found.
Call Render method
Perform text replacement to replace all the report server references with our custom link, which will intercept the requests to report server middle-tier
return the result to client  
(See same output as request 2 ( item id passed in request 3 is not expanded)
 
 
I wrote a console application to demonstrate this behavior
(In this console application I used a modified version of "/AdventureWorks Sample Reports/Company Sales" report by replacing the shared data source with private data source, which is required when using LoadReportDefinition
 
source code of console application:
 
 
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
 
using PlayRSSAPI.ReportService2005;
using PlayRSSAPI.ReportExecution2005;
using System.Xml;
 
namespace PlayRSSAPI
{
    class Program
    {
        static void Main(string[] args)
        {
            ReportingService2005 rs = new ReportingService2005();
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
            rs.Url = "http://rdserver/reportserver/reportservice2005.asmx";
 
            Property pName = new Property();
            pName.Name = "Name";
 
            Property pDesc = new Property();
            pDesc.Name="Description";
 
            Property[] properties = new Property[2];
            properties[0] = pName;
            properties[1] = pDesc;
 
            // "Copy of Company Sales" is modified version of "/AdventureWorks Sample Reports/Company Sales"
            // "Copy of Company Sales" used private datasource instead of shared datasource so the
            string reportName = "/AdventureWorks Sample Reports/Copy of Company Sales";
            //string reportName = "/AdventureWorks Sample Reports/SalesOrderDetail";
            try
            {
                byte[] b = rs.GetReportDefinition(reportName);
                MemoryStream strm = new MemoryStream(b);
                XmlDocument doc = new XmlDocument();
                doc.Load(strm);
 
                // potentially we will add some columns into RDL here ...
                MemoryStream strmOut = new MemoryStream();
                doc.Save(strmOut);
 
                byte[] rdlOut = strmOut.ToArray();
 
                ReportExecution2005.ReportExecutionService res = new ReportExecutionService();
                res.Url = "http://rdserver/reportserver/ReportExecution2005.asmx";
                res.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
               
               
                ReportExecution2005.Warning[] warning;
                ExecutionInfo ei = res.LoadReportDefinition(rdlOut, out warning);
 

                string format = "HTML4.0"; // "HTML";
                string historyID = null;
                string devInfo = @"<DeviceInfo><Toolbar>True</Toolbar><Section>1</Section><HTMLFragment>False</HTMLFragment></DeviceInfo>";
 
               
                string encoding;
                string mimeType;
                string extension;
                string[] streamIDs = null;
                ReportExecution2005.Warning[] warnings = null;
 
                byte[] rptOut = null;
                bool resToggle = false;
                FileStream stream = null;
 
                // first render call
                rptOut = res.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
                stream = File.Create("C:\\Temp\\report.htm", rptOut.Length);
                stream.Write(rptOut, 0, rptOut.Length);
                Console.WriteLine("Result written to the file.");
                stream.Close();
                res = null;
 
                // we are creating a second ReportExecutionService to mimic the page transition in web application
                ReportExecutionService res2 = new ReportExecutionService();
                res2.ExecutionHeaderValue = new ExecutionHeader();
                res2.ExecutionHeaderValue.ExecutionID = ei.ExecutionID;
                res2.Credentials = System.Net.CredentialCache.DefaultCredentials;
               
                resToggle = res2.ToggleItem("7");   // expand "Components" block in the report
                Console.WriteLine(string.Format("Toggle Item 7 {0} ", (resToggle?"OK":"Failed")));
                resToggle = res2.ToggleItem("11");  // expand "2002" block in the report
                Console.WriteLine(string.Format("Toggle Item 11 {0} ", (resToggle?"OK":"Failed")));
               
                // Second Render with 2 items toggled
                rptOut = res2.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
               
             
                stream = File.Create("C:\\Temp\\report_toggle_7_11.htm", rptOut.Length);
                stream.Write(rptOut, 0, rptOut.Length);
                Console.WriteLine("Result written to the file.");
                stream.Close();
                res2 = null;
 
                // we are creating third ReportExecutionService to mimic the page transition in web application
                ReportExecutionService res3 = new ReportExecutionService();
                res3.ExecutionHeaderValue = new ExecutionHeader();
                res3.ExecutionHeaderValue.ExecutionID = ei.ExecutionID;
                res3.Credentials = System.Net.CredentialCache.DefaultCredentials;
 
                resToggle = res3.ToggleItem("27");  // expand "2003" block.
                Console.WriteLine(string.Format("Toggle Item 27 {0} ", (resToggle?"OK":"Failed")));
                // Third Render, this returns the same result as second Render call
                rptOut = res3.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
 

                stream = File.Create("C:\\Temp\\report_toggle_7_11_21.htm", rptOut.Length);
                stream.Write(rptOut, 0, rptOut.Length);
                Console.WriteLine("Result written to the file.");
                stream.Close();
               
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
 
            Console.Read();
 
 
 
        }
    }
}
 
 

Steven Cheng[MSFT]

unread,
Jun 14, 2006, 10:00:20 AM6/14/06
to
Hello Spamme,

Thank you for posting in the MSDN newsgroup.

From your description, I understand you're developing a custom Reporting
service reportviewer control(used in webpage), and your reportviewer
control is using the reporting Service's webservice methods to load the
report and render it. However, you found that there is some issue with the
loaded report's status management when we perform multiple "ToggleItem"
call on a certain report(identify through ExecutionInfo), correct? If
anything I didn't quite get, please feel free to let me know.

Again thanks for your detailed description and demo application which makes
the test quite simplified. I've performed some tests upon the test code you
provided on my local side. I did encounter the same behavior when running
the code against the sample report. Also, I've performed some other tests
through the "ReportExecutionService.LoadReport" method(used for existing
report on server rather than dynamically generated through
"ReportExecutionService.LoadReportDefinition") and found that the issue is
specific to the dynamically generated report. When I perform the test
(call multiple ToggleItems with separate ReportExecutionService instances
), the previous ToggleItem status can be persisted and reflect in the next
rendered report. Here is my new test through
"ReportExecutionService.LoadReport" method loaded report.

=========================================
void NewProcessReport()
{
LocalReportService2005.ReportingService2005 rs = new
LocalReportService2005.ReportingService2005();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rs.Url = "http://localhost/reportserver/reportservice2005.asmx";


Property pName = new Property();
pName.Name = "Name";
Property pDesc = new Property();

pDesc.Name = "Description";


Property[] properties = new Property[2];
properties[0] = pName;
properties[1] = pDesc;

string reportName = "/AdventureWorks Sample Reports/Company
Sales";


LocalReportExecution2005.ReportExecutionService res = new
LocalReportExecution2005.ReportExecutionService();
res.Url =
"http://localhost/reportserver/ReportExecution2005.asmx";
res.Credentials = System.Net.CredentialCache.DefaultCredentials;


string histroyID = null;
ExecutionInfo ei = new ExecutionInfo();

string format = "HTML4.0"; // "HTML";
string historyID = null;
string devInfo =
@"<DeviceInfo><Toolbar>True</Toolbar><Section>1</Section><HTMLFragment>False
</HTMLFragment></DeviceInfo>";

string encoding;
string mimeType;
string extension;
string[] streamIDs = null;

LocalReportExecution2005.Warning[] warnings = null;


byte[] rptOut = null;
bool resToggle = false;

FileStream stream = null;


try
{

//first load
ei = res.LoadReport(reportName,histroyID);



rptOut = res.Render(format, devInfo, out extension, out
encoding, out mimeType, out warnings, out streamIDs);

stream = File.Create(@"D:\temp\sqldir\ssrs\newreport.htm",
rptOut.Length);
stream.Write(rptOut, 0, rptOut.Length);
stream.Close();



ei = res.GetExecutionInfo();



//toggle 7
res.Dispose();
res = new LocalReportExecution2005.ReportExecutionService();
res.Url =
"http://localhost/reportserver/ReportExecution2005.asmx";
res.Credentials =
System.Net.CredentialCache.DefaultCredentials;
res.ExecutionHeaderValue = new ExecutionHeader();
res.ExecutionHeaderValue.ExecutionID = ei.ExecutionID;


res.ToggleItem("7");



rptOut = res.Render(format, devInfo, out extension, out
encoding, out mimeType, out warnings, out streamIDs);

stream = File.Create(@"D:\temp\sqldir\ssrs\newreport1.htm",
rptOut.Length);
stream.Write(rptOut, 0, rptOut.Length);
stream.Close();


ei = res.GetExecutionInfo();


//toggle 11
res.Dispose();
res = new LocalReportExecution2005.ReportExecutionService();
res.Url =
"http://localhost/reportserver/ReportExecution2005.asmx";
res.Credentials =
System.Net.CredentialCache.DefaultCredentials;
res.ExecutionHeaderValue = new ExecutionHeader();
res.ExecutionHeaderValue.ExecutionID = ei.ExecutionID;

res.ToggleItem("11");



rptOut = res.Render(format, devInfo, out extension, out
encoding, out mimeType, out warnings, out streamIDs);

stream = File.Create(@"D:\temp\sqldir\ssrs\newreport2.htm",
rptOut.Length);
stream.Write(rptOut, 0, rptOut.Length);
stream.Close();


//toggle 27
res.Dispose();
res = new LocalReportExecution2005.ReportExecutionService();
res.Url =
"http://localhost/reportserver/ReportExecution2005.asmx";
res.Credentials =
System.Net.CredentialCache.DefaultCredentials;
res.ExecutionHeaderValue = new ExecutionHeader();
res.ExecutionHeaderValue.ExecutionID = ei.ExecutionID;


res.ToggleItem("27");


rptOut = res.Render(format, devInfo, out extension, out
encoding, out mimeType, out warnings, out streamIDs);

stream = File.Create(@"D:\temp\sqldir\ssrs\newreport3.htm",
rptOut.Length);
stream.Write(rptOut, 0, rptOut.Length);
stream.Close();


}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
=================================

In the MSDN document about the "ReportExecutionService.LoadReportDefinition
Method", it said that

"Reports instantiated with the LoadReportDefinition method are temporary.
They are not represented in the report server namespace, and are discarded
when the server session expires. "

I'm suspecting the cause may be such temporary report won't have the same
status management like existing reports on reportserver.

Anyway, I'll perform some further research in my internal database to see
whether this is a known behavior.

Thanks,

Steven Cheng
Microsoft MSDN Online Support Lead


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

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

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


This posting is provided "AS IS" with no warranties, and confers no rights.

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

InvalidLastName

unread,
Jun 14, 2006, 11:17:29 AM6/14/06
to
Steven,
Your understandings are correct. Thanks for providing the sample code. I ran your code and I did see the toggleItem works as expected with LoadReport method.
However, we need to be able to add coloumns in the report based on user's selections, so we choose to generate RDL on the fly.
It is important to us to use LoadReportDefinition for loading the dynamically generated RDL.
 
I am looking forward to see if you find any resolution on this issue
 
FYI, the paging works, by setting DeviceInfo/Section, without any problem while executing report with LoadReportDefinition. What I don't understand is why RS preseves the ToggleItem states from the first time, but ignores the following ToggleItem calls.
 
 
 
Thanks
 
ILN
 
 
 
"Steven Cheng[MSFT]" <stc...@online.microsoft.com> wrote in message news:3hNatr7j...@TK2MSFTNGXA01.phx.gbl...

InvalidLastName

unread,
Jun 14, 2006, 11:43:45 AM6/14/06
to
Hi Steven,
Just want to let you know the ToggleItem works very well if I used the Microsoft.Reporting.WebForms.ReportViewer.ServerReport.LoadReportDefinition to load report in the ReportViewer web control.
It looks like the middle-tier does maintain the state of each toggled item, but SOAP version ToggleItem doesn't work as the toggle item links in ReportViewer (URL Access ?) web control.
 
Thanks
 
 
"Steven Cheng[MSFT]" <stc...@online.microsoft.com> wrote in message news:3hNatr7j...@TK2MSFTNGXA01.phx.gbl...

Steven Cheng[MSFT]

unread,
Jun 15, 2006, 4:30:01 AM6/15/06
to
Thanks for your further response,

As for the further test on the webform reportviewer control, would you also
provide me the detailed code snippet (you manipulate the reportviewer to
loadReportdefinition and then render it)? I've just performed some test
through the ReportViewer.ServerReport.LoadReportDefinition method, however,
it will always report the following error

"Execution 'xxxxxxxxxxxxxxxx' cannot be found

Have you ever encountered this error? Also, based on my investigation on
the reportViewer control's internal code, it also use the ReportService2005
and ReportexecutionEngine webservice to perform the task (such as Load
Report or LoadReportDefinition).

Looking forward to your response.

Regards,

InvalidLastName

unread,
Jun 15, 2006, 10:50:31 PM6/15/06
to
Hi Steven,
Here are the code segments for using ReportViewer:
 

using

System;

using

System.Data;

using

System.Configuration;

using

System.Collections;

using

System.Web;

using

System.Web.Security;

using

System.Web.UI;

using

System.Web.UI.WebControls;

using

System.Web.UI.WebControls.WebParts;

using

System.Web.UI.HtmlControls;

using

System.IO;

using

System.Xml;

using

ReportViewerDemo.ReportExecution2005;

using

ReportViewerDemo.ReportService2005;

namespace

ReportViewerDemo

{

public partial class RSReportViewer : System.Web.UI.Page

{

private const string REPORT_SERVER_DNS = "rdserver";

private static string ReportingServiceURL = "http://{0}/reportserver/reportservice2005.asmx
";

private static string ReportExecution2005URL = "http://{0}/reportserver/ReportExecution2005.asmx";

 

 

protected ReportingService2005 _rs = new ReportingService2005();

protected ReportExecutionService _res = new ReportExecutionService();

 

static RSReportViewer()

{

ReportingServiceURL =

string.Format(ReportingServiceURL, REPORT_SERVER_DNS);

ReportExecution2005URL =

string.Format(ReportExecution2005URL, REPORT_SERVER_DNS);

}

protected void Page_Load(object sender, EventArgs e)

{

ReportViewer1.ProcessingMode = Microsoft.Reporting.WebForms.

ProcessingMode.Remote;

ReportViewer1.ServerReport.ReportServerUrl =

new Uri( string.Format("http://{0}/reportserver/", REPORT_SERVER_DNS));

PrepareReport(

"/AdventureWorks Sample Reports/Copy of Company Sales", ReportViewer1);

}

 

private void PrepareReport(string reportName, Microsoft.Reporting.WebForms.ReportViewer rv)

{

_rs.Credentials = System.Net.

CredentialCache.DefaultCredentials;

_rs.Url = ReportingServiceURL;

_res.Credentials = System.Net.

CredentialCache.DefaultCredentials;

_res.Url = ReportExecution2005URL;

_res.ExecutionHeaderValue =

new ExecutionHeader();

try

{

byte[] b = _rs.GetReportDefinition(reportName);

MemoryStream strm = new MemoryStream(b);

XmlDocument doc = new XmlDocument();

doc.Load(strm);

// modify xml for ad-hoc report

MemoryStream strmOut = new MemoryStream
();

doc.Save(strmOut);

strmOut.Position = 0;

// must call this

rv.ServerReport.LoadReportDefinition(strmOut);

System.Diagnostics.

Debug.WriteLine(rv.ServerReport.GetExecutionId());

 

strm.Close();

strmOut.Close();

 

 

}

catch (Exception ex)

{

System.Diagnostics.

Debug.WriteLine(ex.ToString());

throw ex;

}

}

}

}

"Steven Cheng[MSFT]" <stc...@online.microsoft.com> wrote in message news:UsqPzXFk...@TK2MSFTNGXA01.phx.gbl...

Wei Lu

unread,
Jun 21, 2006, 7:25:56 AM6/21/06
to
Hi Spamme,

This is a quick note to let you know that I am performing research on this
issue and will get back to you as soon as possible. I appreciate your
patience.


Sincerely,

Wei Lu
Microsoft Online Community Support

Wei Lu [MSFT]

unread,
Jun 22, 2006, 5:38:36 AM6/22/06
to
Hi Spamme,

This is a quick note to let you know that I could re-produce this issue and
I still need some time to perform research and try to found a resolution. I
appreciate your patience.


Sincerely,

Wei Lu
Microsoft Online Community Support

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

InvalidLastName

unread,
Jun 22, 2006, 7:01:40 PM6/22/06
to
Wei,
Really appreciate it. Please let me know if you need any code snippet from
me

Regards-

"Wei Lu [MSFT]" <we...@online.microsoft.com> wrote in message
news:PePrp%23dlGH...@TK2MSFTNGXA01.phx.gbl...

Abe

unread,
Jun 29, 2006, 1:13:42 PM6/29/06
to
Were either of you able to find a solution? The same issue occured in
our application after upgrading to SQL Server SP1. When pointing at a
server that is not upgraded (with identical contents) then ToggleItem
will properly toggle. One thing that I did notice is that in the
ReportServerTEMPdb in the SessionData table, the column
AwaitingFirstExecution is set to 1 when we call ToggleItem and
re-render the report. It seems like the session is resetting. Is this
a different issue?

Any help would be appreciated.
Thanks,
Abe

Wei Lu [MSFT]

unread,
Jun 30, 2006, 5:56:28 AM6/30/06
to
Hi Spamme,

I have done some researching on this issue. I found that the session
created in the Report Temp database by LoadReportDefinition method will be
different with the LoadReport method.

This issue is most like that the LoadReportDefinition method does not hold
the report session.

I still need some time to contact with the development team to check
whether we could get a workaround.

Dave

unread,
Jul 7, 2006, 10:06:12 AM7/7/06
to
Hi. I have the same exact issue as the above two people and I am
anxiously awaiting your reply. Whenever we do a webservice.ToggleItem,
the report session seems to get lost. The issue occurs in SP1 of Sql
Server 2005. We have the same exact code running on a server without
SP1 and ToggleItem works perfectly.

Any help is appreciated, thank you.

Dave

InvalidLastName

unread,
Jul 26, 2006, 12:17:22 PM7/26/06
to
Hi,
I accidentally found out by adding "<StreamRoot>your stream root goes here</StreamRoot>" into DeviceInfo will resolve this issue.
 
 
For example:
This won't work
string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar><Section>1</Section><HTMLFragment>False</HTMLFragment></DeviceInfo>";
 
But this will make toggle item work
 
string devInfo = @"<DeviceInfo><StreamRoot></StreamRoot><Toolbar>False</Toolbar><Section>1</Section><HTMLFragment>False</HTMLFragment></DeviceInfo>";
 
Hope this will help
 
However,I do notice the device info for html output described in BOL seems not work as expected
 
For example:
from BOL

HTMLFragment

Indicates whether an HTML fragment is created in place of a full HTML document. An HTML fragment includes the report content in a TABLE element and omits the HTML and BODY elements. The default value is false. If you are rendering to HTML using the Render method of the SOAP API, you need to set this device information to true if you are rendering a report with images. Rendering using SOAP with the HTMLFragment property set to true creates URLs containing session information that can be used to properly request images. The images must be uploaded resources in the report server database. (ILN: I am seeing different behavior ...)

 

Toolbar

Indicates whether to show or hide the toolbar. The default of this parameter is true. If the value of this parameter is false, all remaining options (except the document map) are ignored. If you omit this parameter, the toolbar is automatically displayed for rendering formats that support it.

The Report Viewer toolbar is rendered when you use URL access to render a report. The toolbar is not rendered through the SOAP API. However, the Toolbar device information setting affects the way that the report is displayed when using the SOAP Render method. If the value of this parameter is true when using SOAP to render to HTML, only the first section of the report is rendered. If the value is false, the entire HTML report is rendered as a single HTML page. (ILN: I am seeing different behavior ...)

 
 
- InvalidLastName
 
 

Steven Cheng[MSFT]

unread,
Jul 27, 2006, 12:11:41 AM7/27/06
to
Hello David,

Thank you for the followup.

Due to some urgent issue I was absent perviously and our member Wei has
continued to help you on this issue. I was told that Wei has helped
leverage some other engineers from our product team to work with on this
issue offline. Have they helped you made any further progress or have you
informed this finding to them, I think they can help find more information
on this behavior you find.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead

This posting is provided "AS IS" with no warranties, and confers no rights.

Dave

unread,
Aug 3, 2006, 8:45:13 AM8/3/06
to
Hi. We actually figured out what was going on. The issue lied in
setting the parameters. In pre-SP1, you could set parameters on every
postback and if they did not change, the execution did not get reset
and hence toggling works.

However, in SP1, everytime the parameters are set, the report execution
is reset. This causes toggling and sorting to fail.

The workaround was to only set parameters when they have changed. I am
still curious as to why this functionality has changed in SP1 as it was
undocumented. Is it a new feature or bug? I am currently working with
support on this.

Dave

Wei Lu [MSFT]

unread,
Aug 4, 2006, 2:46:25 AM8/4/06
to
Hi Dave,

Thank you for your feedback.

Have you tried the suggestion that InvalidLastName posted?

I have provide the information to the PSS support and they will follow up
with you. Thank you!

leah...@gmail.com

unread,
Apr 30, 2019, 10:23:51 AM4/30/19
to
what ended up happening with this? I am facing this now.
0 new messages