asp.net-mvc - net - mvc c#
Botones CrystalReportViewer rotos usando MVC Framework (2)
Pudimos hacer que el visor de informes funcionara y lo hemos estado usando durante los últimos meses en producción sin ningún problema.
- Tenemos un controlador de informes que enumera los enlaces a los informes que queremos ejecutar
- Al hacer clic en uno de los enlaces realizaremos una llamada ajax al back-end y devolveremos una página parcial donde podemos completar todos los parámetros que necesitamos.
- Una vez completados los parámetros, enviamos el formulario a ''/ reports / Name of Report''.
- De vuelta en el controlador de Informes llamamos a SQL, devolvemos nuestros datos, y luego llamamos a una vista diferente llamada ''Informe completo''
- La vista ''Informe completo'' solo tiene un control de visor de informes de cristal en el que toma automáticamente los datos del informe que le pasamos a través de ViewData, rellena el informe, lo renderiza y lo envía al usuario
Todo parece funcionar bien.
ACTUALIZAR
He agregado un código y una aclaración a los pasos que originalmente mencioné arriba. El elemento clave que dejé fue que hay algún código detrás con la Vista final, por lo que funcionará con Crystal Reports. El código detrás es mínimo, pero necesario. Para que Crystal Reports funcione, va a terminar con los siguientes archivos:
- Un archivo de diseño .rpt donde diseña el informe
- Un archivo aspx que contiene el control Crystal Reports Report. Este es el archivo que tendrá algún código detrás.
Detalles sobre cómo crear una vista que funcionará con Crystal Reports:
- Cree el diseño de su informe utilizando Crystal Reports Designer. El archivo resultante será un archivo .rpt. Por el bien de este ejemplo, llamemos a este archivo AllJobsSummaryReportLayout.rpt.
- Al diseñar su informe, para los ''Campos de la base de datos'', seleccione una de las entidades comerciales o DTO que contiene los resultados provenientes de SQL.
- Dejando a un lado, tenemos algunos objetos de transferencia de datos (DTO) en nuestro sistema que no contienen nada más que valores escalares y cadenas, no hay inteligencia en estos DTO. Cuando se llama al Controlador, llama al Modelo, el Modelo para la mayoría de estos informes devuelve una Lista de DTO que luego pasamos a la Vista que se va a representar. Estos DTO no saben cómo autoexplicarse, mostrarse a sí mismos, solo contienen los valores reales devueltos desde SQL que luego alguien más representa.
Una vez que se completa el archivo de Crystal Reports, el AllJobsSummaryReportLayout.rpt, diseñamos nuestro controlador. En el Controlador tomamos los parámetros necesarios para ejecutar el informe, llamamos al Modelo. El Modelo devuelve nuestra lista de DTO, como se ve en el siguiente fragmento del Controlador:
var reportViewData = model.AllJobsSummaryQuery(startDate, endDate); if (0 != reportViewData.Count()) { var report = new AllJobsSummaryReportLayout(); report.SetDataSource(reportViewData); report.SetParameterValue("startDate", startDate); report.SetParameterValue("endDate", endDate); ViewData["ReportData"] = report; returnView = "AllJobsSummaryView"; } else returnView = "noReportView"; return View(returnView);
Tenga en cuenta un par de elementos aquí, estamos creando un ''informe'' variable que es un tipo del archivo de diseño de informe de Crystal, AllJobsSummaryReportLayout.rpt, que hemos creado anteriormente.
Una vez que creamos la variable ''informe'', establecemos los valores de fuente de datos y cualquier parámetro que necesitemos, y agrupamos el elemento en ViewData.
Ahora echemos un vistazo a AllJobsSummaryView.aspx. Este archivo tiene un formulario con Crystal Reports Viewer y un código detrás del archivo:
<%@ Page Title="All Jobs Summary Report" Language="C#" AutoEventWireup="true" CodeBehind="AllJobsSummaryView.aspx.cs" Inherits="V.Views.Reports.AllJobsSummaryView"%> <%@ Register Assembly="CrystalDecisions.Web, Version=10.5.3700.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" Namespace="CrystalDecisions.Web" TagPrefix="CR" %> <form id="form1" runat="server"> <div> <a href="/Reports" id="Report"><< Return to Report Main Page</a><br /> <CR:CrystalReportViewer ID="ReportViewer" runat="server" AutoDataBind="True" EnableDatabaseLogonPrompt="False" EnableParameterPrompt="False" HasCrystalLogo="False" DisplayGroupTree="False" HasDrillUpButton="False" HasToggleGroupTreeButton="False" HasViewList="False" HasSearchButton="False" EnableDrillDown="False" EnableViewState="True" Height="50px" ReportSourceID="CrystalReportSource1" Width="350px" /> <CR:CrystalReportSource ID="CrystalReportSource1" runat="server"> <Report FileName="AllJobsSummaryReportLayout.rpt"> </Report> </CR:CrystalReportSource> </div> </form>
Y el código detrás del archivo:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace V.Views.Reports { public partial class AllJobsSummaryView : ViewPage { protected void Page_Init(object sender, EventArgs e) { ReportViewer.ReportSource = ViewData["ReportData"]; } protected void Page_Unload(object sender, EventArgs e) { ((AllJobsSummaryReportLayout)ViewData["ReportData"]).Close(); ((AllJobsSummaryReportLayout)ViewData["ReportData"]).Dispose(); } } }
La Page_Unload es la clave, sin ella tendrá un error generado por Crystal Reports ''Ha excedido la cantidad máxima de informes configurados por su administrador''.
Este método todavía funciona en un entorno de producción durante más de dos años.
Estamos utilizando el marco MVC (versión 5) y el control CrystalReportViewer para mostrar nuestros informes. No puedo hacer que funcione ninguno de los botones en la parte superior del control del visor de informes.
Si estoy trabajando con el informe ''HoursSummary''. Si coloco el cursor sobre cualquiera de los botones en el visor de informes en IE, el enlace que se muestra en la parte inferior de las páginas es ''../HoursSummary''. Esto crea una url de '' http: // localhost / HoursSummary ''. No hay un controlador ''HoursSummary'' así que sigo recibiendo errores 404.
- Creo que quiero redireccionar a '' http: // localhost / reports / HoursSummary '' ya que tengo un controlador de informes. Si este es el método correcto, ¿alguien sabe qué propiedad debo configurar en el control CrystalReportViewer para que esto suceda?
- ¿Hay un método más fácil para manejar esta situación?
Si eso es un control de servidor, no funcionará. ASP.NET MVC no utiliza ninguna devolución de datos, por lo que la mayoría de los controles del servidor de formularios web no funcionan.
Lo que puede hacer es incrustar el visor de informes en un iFrame y generarlo en su vista de MVC. El iframe puede apuntar a una página fuera de las cosas de MVC, por ejemplo, en una subcarpeta llamada Legacy o algo así.