Monday, March 19, 2012

Getting ReportViewer client parameters at runtime

I cannot seem to do the following:

1) I have a report that uses the ASP.NET 2.0 Report Viewer against a RS2005 report that has parameters. Some have default values. One is a text box. Others are drop-down lists.
2) I have ShowParameterPrompts = true and am presented the parameter area upon first visit to the page.
3) I fill in the parameters on the web browser page and click the View Report button
4) Now, on the server side, I want to examine the parameter values (in the Page_Load event). When I do a GetParameters on the ServerReport of the ReportViewer, I receive back a collection of the default parameters values, not the values that I just submitted.

How do I see the parameter values submitted by the client?

Other information I found while investigating this:

1) If I click on the View Report button again (and again), GetParameters always return the previous set of parameters, not the current values that the client submitted.
2) If I look at the Request.Forms collections I can see values for controls that have been generated by the ReportViewer control in the parameters area - where the values are different when the client submitts new parameters.
3) If I do a GetParameters in the pages Page_PreRender event, I see the same behavior.
4) I can do a walk of the control tree inside the report view control instance and see the various controls created for the parameters area. Those controls have the Request.Form values in them.
5) The Report Viewer, load, report refresh and prerender events don't seem to be much help either.

I could hack a solution using the control tree or the Request.Form values, but that's rather inelegant and relies on Micrsoft not changing the ReportViewer control's behavior.

Any explanations of what is happening here would be appreciated. Thanks,

ER Doll

I am having a similar problem. Have you found a solution, specifically to number 1 in the second section of your message?

CWaitz

|||

I am also trying to find how to get the parameters that the user has set when they hit the View Report button. But I think this is what happens when you do a GetParameters when you hit the View Report button on the ReportViewer control:

When you do a GetParameters() it gets the values of the parameters of the report that is already generated on the screen. So if you were to change the parameters and click View Report, in your Page_Load when you call GetParameters(), this is looking at the parameters before your new report is generated. So if you wanted the new parameters that the user has inputted, you would need to wait for the report to get generated then do a postback and use GetParameters.

If anyone knows how to get the parameter values the user has selected before the report is generated, please let us know.Huh?

|||

Examine your parameters in isPostBack block.

protected void Page_Load(object sender, EventArgs e){if(isPostBack) {//EXAMINE }}
|||

bullpit:

Examine your parameters in isPostBack block.

protected void Page_Load(object sender, EventArgs e){if(isPostBack) {//EXAMINE }}

I've been doing this but it doesn't work. If it were a DateTime parameter then it would work because when you change the date in ReportViewer it does a Postback which updates the ReportViewer. Is it possible to always do a Postback whenever a value for a parameter is changed? Even for String parameters that appear as textboxes? This would solve my problem.

|||

What about using TextChanged and SelectedIndex changed event. Make a function where you load your Reportviewer. Call that function everytime there is text changed or selected index changed.

|||I don't have access to those events since the controls are rendered automatically in the ReportViewer depending on what type of parameter it is. I'm trying to see if there is a property in the actual parameter creation when creating the report. There has to be because one of my reports that has a dropdown list did a postback whenever the selection changed. But another report didn't. I have to find out how this happened...|||

The values of the parameters are stored in the view state of the parameter controls. Unfortunately, as you mentioned, you don't have direct access to those controls at run time. However, you do have access to them through the Controls collection of the ReportViewer, if you know what to look for. The following code will extract the currently selected parameter values. NOTE: this code uses reflection and is dependent on the internal implementation of the parameter controls. This is necessary since the ReportViewer does not expose the values of these controls in any other way.

Public Function GetCurrentParameters(ByVal viewerAs Microsoft.Reporting.WebForms.ReportViewer)As ReportParameter()Dim paramsAreaAs Control = FindParametersArea(viewer)Dim paramsAs New List(Of ReportParameter)()FindParameters(paramsArea, params)Return params.ToArray()End FunctionPrivate Function FindParametersArea(ByVal viewerAs Microsoft.Reporting.WebForms.ReportViewer)As ControlFor Each childAs ControlIn viewer.ControlsIf child.GetType().Name ="ParametersArea"ThenReturn childEnd IfNextReturn NothingEnd FunctionPrivate _ParameterControlTypeAs Type = System.Reflection.Assembly.GetAssembly(GetType(Microsoft.Reporting.WebForms.ReportViewer)).GetType("Microsoft.Reporting.WebForms.ParameterControl")Private Sub FindParameters(ByVal parentAs Control,ByVal paramsAs List(Of ReportParameter))Dim paramAs ReportParameterDim paramInfoAs ReportParameterInfoDim paramValuesAs String()For Each childAs ControlIn parent.ControlsIf _ParameterControlType.IsAssignableFrom(child.GetType())ThenparamInfo =CType(GetPropertyValue(child,"ReportParameter"), ReportParameterInfo)If paramInfoIs Nothing Then ContinueForparamValues =CType(GetPropertyValue(child,"CurrentValue"),String())If Not paramValuesIs Nothing AndAlso paramValues.Length > 0Thenparam =New ReportParameter()param.Name = paramInfo.Nameparam.Values.AddRange(paramValues)params.Add(param)End IfEnd IfFindParameters(child, params)NextEnd SubPublic Function GetPropertyValue(ByVal targetAs Object,ByVal propertyNameAs String)As ObjectReturn target.GetType().GetProperty(propertyName, BindingFlags.IgnoreCaseOr BindingFlags.InstanceOr BindingFlags.NonPublicOr BindingFlags.Public).GetValue(target,Nothing)End Function
|||

autofed,

Your code saved my ass. It worked like a charm. Thank you.

No comments:

Post a Comment