Using ReportView

1

I would like some help. I am using ReportView to generate a report from the 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 at the time I'm going to 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 report data source object must be of type   System.Data.DataTable, System.Collections.IEnumerable, or   System.Web.UI.IDataSource.

Someone could give me a hand. Thank you !!

    
asked by anonymous 25.10.2016 / 12:41

1 answer

1

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

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

You would have to create a List<Cliente> and add that single client in 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);
            }
        }
    }
    
25.10.2016 / 13:32