Using the Reportview

Asked

Viewed 410 times

1

I’d like some help. I’m using the ReportView to generate a report from id passed as parameter:

public ActionResult Relatorio(Guid id)
{
    LocalReport relatorio = new LocalReport();

    //Caminho onde o arquivo do Report Viewer está localizado
    relatorio.ReportPath = Server.MapPath("~/Report/RelatorioCliente.rdlc");
    //Define o nome do nosso DataSource e qual rotina irá preenche-lo, no caso, nosso método criado anteriormente RepositorioPedido.SelecionaPedido(codPedido)));

    relatorio.DataSources.Add(new ReportDataSource("DataSetCliente", _clienteRepositorio.BuscarTodos().AsEnumerable().FirstOrDefault(c=>c.ClienteId == id)));

    string reportType = "PDF";
    string mimeType;
    string encoding;
    string fileNameExtension;

    string deviceInfo =
      "<DeviceInfo>" +
      " <OutputFormat>PDF</OutputFormat>" +
      " <PageWidth>9in</PageWidth>" +
      " <PageHeight>11in</PageHeight>" +
      " <MarginTop>0.7in</MarginTop>" +
      " <MarginLeft>2in</MarginLeft>" +
      " <MarginRight>2in</MarginRight>" +
      " <MarginBottom>0.7in</MarginBottom>" +
      "</DeviceInfo>";

    Warning[] warnings;
    string[] streams;
    byte[] bytes;

    //Renderiza o relatório em bytes
    bytes = relatorio.Render(
    reportType,
    deviceInfo,
    out mimeType,
    out encoding,
    out fileNameExtension,
    out streams,
    out warnings);

    return File(bytes, mimeType);
}

But as soon as I generate the report, it gives an error on the line:

relatorio.DataSources.Add(new ReportDataSource("DataSetCliente", _clienteRepositorio.BuscarTodos().AsEnumerable().FirstOrDefault(c=>c.ClienteId == id)));

And says that:

The data source object of the report shall be of the System.Data.Datatable, System.Collections.Ienumerable or System.Web.UI.Idatasource.

Someone could give me a hand. Thank you!!

1 answer

1

The error is very clear: should be passed as data source some object that implements IEnumerable, IDataSource, or that is DataTable.

The command FirstOrDefault() that you are using will bring only one instance T client, which does not implement anything that is contracted. You must "envelop" that client instance in a DataSet or IEnumerable however much will be displayed only one record.

You’d have to create one List<Cliente> and add that single client to the list, and move on to the report.

I have the following implementation for this with Reportviewer in WPF, the idea is the same:

private void InicializarRelatorio(string nomeRelatorio, Dictionary<string, IEnumerable> dados)
    {
        //percorre o dicionario para adicionar as fontes de dados no relatorio
        foreach (var dado in dados)
        {
            ReportDataSource reportDataSource = new ReportDataSource();
            reportDataSource.Name = dado.Key; //nome do DataSet no .rdlc
            reportDataSource.Value = dado.Value; // objeto(lista) de dados
            reportViewer.LocalReport.DataSources.Add(reportDataSource);
        }

        //carrega o relatorio que deve estar na pasta do executavel. o arquivo rdlc deve estar CopyToLocal
        reportViewer.LocalReport.ReportPath = AppDomain.CurrentDomain.BaseDirectory + @"Relatorios\" + nomeRelatorio;
        reportViewer.RefreshReport();
    }

    private void btnFichaCliente_Click(object sender, RoutedEventArgs e)
    {
        using (ClienteBusiness business = new ClienteBusiness())
        {
            int codigoCliente = Convert.ToInt32(cboClientes.SelectedValue);
            var cliente = business.RelatorioFichaCliente(codigoCliente);

            if (cliente.Count > 0)
            {
                Dictionary<string, IEnumerable> dicDados = new Dictionary<string, IEnumerable>();
                dicDados.Add("ClienteDataSet", cliente);

               InicializarRelatorio("RelCliente.rdlc", dicDados);
            }
        }
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.