sábado, 28 de marzo de 2015

Como solucionar el bug del control ReportViewer que muestra todos los campos con #Error

Hace tiempo venimos trabajando con ReportViewer y nunca habíamos tenido mayores problemas con el mismo, hasta el día de ayer que sucedió lo que paso a contarles a continuación.

Teníamos unos reportes hechos en una aplicación web que corría con la versión vieja del ReportViewer (la que venía con VS2010 ... no recuerdo el número de versión exacta) corriendo sobre .NET 2.0 y generando reportes localmente; teníamos la necesidad de migrarlo a un sitio nuevo hecho con VS2013 corriendo .NET 4.5.2. La migración se realizó de manera transparente, es decir, no hubo que meterle mano a los archivos rldc ni nada por el estilo. Al momento de probarlos tampoco hubo problemas,  los reportes se generaron correctamente. 

Hasta ahí íbamos bien, llegó el momento de ponerlo en producción y al momento de generar el reporte... ésto es lo que sucedió:


Nos generó el reporte con todos sus campos marcados con el tag "#Error" !. 

Antes de seguir cabe aclarar que algunos campos son expresiones (ej: =IIf(Fields!Cost.Value > Fields!Revenue.Value, "Red", "Black") pero la mayoría no lo son e igual se mostraban con el infame mensaje de "#Error", lo que descartaba algún bug que pudiera tener la expresión.

Pero, ¿que pasó? 

Bien, al parecer es un tema relacionado con el cambio en las políticas de seguridad de .NET 4 y el ReportViewer corriendo en un AppDomain con permisos mas restrictivos, por lo que tenemos dos opciones posibles para solucionarlo:

1) Agregar al web.config la siguiente linea:"<trust legacyCasModel="true" level="Full" />


2) Al momento de generar el reporte agregar las dos líneas que se marcan a continuación: 

protected void GenerarArchivoPdf(string fileName, ReportViewer rpv)
{
Warning[] warnings = null;
string[] streamids = null;
string mimeType = null;
string encoding = null;
string extension = null;
const string deviceInfo = "";
System.Security.PermissionSet sec = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.Unrestricted);
rpv.LocalReport.SetBasePermissionsForSandboxAppDomain(sec);
//Generar el archivo
byte[] archivo = rpv.LocalReport.Render("PDF", deviceInfo, mimeType, encoding, extension, streamids, warnings);
//Guardar el archivo en la carpeta temporal para referenciarlo como adjunto del mensaje
My.Computer.FileSystem.WriteAllBytes(fileName, archivo, true);
}

En nuestro caso lo resolvimos utilizando la opción 2

Si quieren leer mas acerca de este tema les recomiendo:



Espero les sea de utilidad y me despido hasta la próxima!