asp.netreportviewerreportviewer2008

ReportViewer resets parameters after submit


I'm showing a remote report in a ReportViewer control. The report loads with a few default parameters. So far everything is ok.

But when i change a few input values and hit View Report then the report simply shows the data with the default values. The parameters that i changed in the input fields are also reset.

All the code i have is this:

apsx

<rsweb:ReportViewer ID="ReportViewer1" runat="server" Font-Names="Verdana"
    Font-Size="8pt" Height="642px" ProcessingMode="Remote" Width="100%">
    <ServerReport ReportPath="http://server.com/Product/Dashboards/test.rdl" 
        ReportServerUrl="http://server.com/ReportServer" />
</rsweb:ReportViewer>

The CodeBehind is basically empty. All it has now is an empty Page_Load.

That is all my code.

But it feels like a ViewState issue? But I am not sure where to look.

Anyone any idea why the parameters are resrt when I press on the View Report button?


Solution

  • I solved this by setting the parameters myself in the Code Behind. So when the report is submitted, i then get all the entered data, put that in a ReportParameters collection.

    But unfortunately this wasn't as easy and straight forward as one would think. At first you might think this is stored in: YourReport.ServerReport.GetParameters(). But that is not the case!

    To get the submitted values from your report you can use the following code:

    Get report submitted parameters

    public ReportParameter[] GetCurrentParameters(Microsoft.Reporting.WebForms.ReportViewer viewer)
    {
        Control params1Area = FindParametersArea(viewer);
        List<ReportParameter> params1 = new List<ReportParameter>();
        FindParameters(params1Area, params1);
        return params1.ToArray();
    }
    
    private Control FindParametersArea(Microsoft.Reporting.WebForms.ReportViewer viewer)
    {
        foreach (Control child in viewer.Controls)
        {
            if (child.GetType().Name == "ParametersArea")
                return child;
        }
    
    
        return null;
    }
    
    private void FindParameters(Control parent, List<ReportParameter> params1)
    {
        Type _ParameterControlType = System.Reflection.Assembly.GetAssembly(typeof(Microsoft.Reporting.WebForms.ReportViewer)).GetType("Microsoft.Reporting.WebForms.BaseParameterInputControl");
    
        ReportParameter param;
        Microsoft.Reporting.WebForms.ReportParameterInfo paramInfo;
        String[] paramValues;
        foreach (Control child in parent.Controls)
        {
            if (_ParameterControlType.IsAssignableFrom(child.GetType()))
            {
                paramInfo = (Microsoft.Reporting.WebForms.ReportParameterInfo)GetPropertyValue(child, "ReportParameter");
                if (paramInfo == null)
                    continue;
    
    
                paramValues = (string[])GetPropertyValue(child, "CurrentValue");
                if (paramValues != null && paramValues.Length > 0)
                {
                    param = new ReportParameter();
                    param.Name = paramInfo.Name;
                    param.Values.AddRange(paramValues);
                    params1.Add(param);
                }
            }
            FindParameters(child, params1);
        }
    }
    
    public object GetPropertyValue(object target, string propertyName)
    {
        return target.GetType().GetProperty(propertyName, System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public).GetValue(target, null);
    }
    

    Source: http://forums.asp.net/t/1057747.aspx/1 (Also Visual Basic examples)

    You invoke those methods by just using the following line of code. Preferably in a if(IsPostBack) scope within your Page_Load for example.

    ReportParameter[] reportParameters = GetCurrentParameters(ReportViewer1);
    

    It is then possible to overwrite the submitted values if you also have custom textfields. You can easily do that like so:

    reportParameters[4] = new ReportParameter("year", "2013", true);
    

    You obviously have to know what param is stored at index 4. But you could also make an easy lookup function that searches for the reportParameter with a specific name. So in my case year.

    Simple parameter lookup

    protected void ChangeParameterValue(String name, String newValue, ref ReportParameter[] parameters)
    {
        foreach (ReportParameter param in parameters)
        {
            if (String.Equals(param.Name, name))
            {
                param.Values[0] = newValue;
                break;
            }
        }
    }
    

    You use that like so:

    ChangeParameterValue("year", "2013", ref reportParameters);
    

    This way you don't have to worry about at what index a certain parameter is placed.