Principales respuestas
Los reportes no se muestran cuando publico mi proyecto web

Pregunta
-
Saludos, estoy trabajando en un proyecto web con asp.net, c# y Crystal Reports y me muestra el siguiente error solo cuando lo publico, si lo ejecuto desde el Visual Studio todo anda perfectamente:
Error No se pudo abrir la conexión. Nombre_Reporte 10372_12704_{CFC8BA14-9714-4F2E-8B31-54C79E897437}.rpt
He notado que cuando reinicio el IIS los numeros que muestra al lado del nombre del reporte cambian.Lo he intentado todo, habilite las aplicaciones de 32bits, Reinstale CRforVS 13.0.21, y el runtime de 32 y 64 bits. 13.0.21. y revise los parametros.
A continuación mostrare los codigos:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Reportes.aspx.cs" Inherits="SisgemWeb.Paginas.Reportes" %> <%@ Register assembly="CrystalDecisions.Web, Version=13.0.3500.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" namespace="CrystalDecisions.Web" tagprefix="CR" %> <asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="FeaturedContent" runat="server"> </asp:Content> <asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server"> <asp:Button ID="BtnCerraR" runat="server" class="btn btn-warning" Text="Cerrar" Visible="true" OnClick="BtnCerraR_Click" /> <CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server" AutoDataBind="True" EnableParameterPrompt="False" GroupTreeImagesFolderUrl="" Height="1202px" ReportSourceID="CrystalReportSource2" ToolbarImagesFolderUrl="" ToolPanelView="None" ToolPanelWidth="200px" Width="903px" /> <CR:CrystalReportSource ID="CrystalReportSource2" runat="server"> <Report FileName="Nombre_Reporte.rpt"> </Report> </CR:CrystalReportSource> </asp:Content>
private void reporte() { try { ReportDocument reporte = new ReportDocument(); ConnectionInfo coninfo = new ConnectionInfo(); String strRutaArchivo = Server.MapPath("Nombre_Reporte.rpt"); reporte.Load(strRutaArchivo); CrystalReportSource2.ReportDocument.SetParameterValue("vContri", Session["CodCon"]); CrystalReportSource2.ReportDocument.SetParameterValue("vBD", "BD"); coninfo.ServerName = "Server"; coninfo.DatabaseName = "BD"; coninfo.UserID = "root"; coninfo.Password = "******"; CrystalReportViewer1.ReportSource = reporte; CrystalReportViewer1.DataBind(); } catch (Exception ex) { mtvAddMessageModal(ex.Message, MessageType.error); } }
Otra cosa, uno de los reportes tiene un subinforme, que quizas con las soluciones que me den no se resuelva ya que no muestra ese error, solo muestra los controles del report viewer y mas nada, pero solo es cuando lo publico, cuando lo ejecuto desde el Visual Studio todo anda bien.
Necesito respuesta urgente por favor. si me falto por indicar algo lo comentan.
- Editado Handelsr jueves, 14 de diciembre de 2017 19:40
Respuestas
-
Tiene toda la pinta de ser un problema de credenciales. El Crystal intenta abrir una conexión al servidor de base de datos para traer los datos del informe, y no lo consigue porque la cuenta bajo la que se está ejecutando (la del Pool en IIS, no la del usuario que se conecta desde el navegador) no tiene permiso de acceso al servidor de base de datos. En tiempo de desarrollo no se nota porque la cuenta bajo la que se ejecuta es la del usuario que está rodando el proyecto en Visual Studio, que sí que tiene permisos en la base de datos.
Solución: O bien cambiar la cuenta del Pool y poner una que tenga los permisos requeridos, o bien ir al servidor de base de datos y conceder permisos a la cuenta del Pool.
- Propuesto como respuesta Pablo RubioModerator viernes, 15 de diciembre de 2017 17:23
- Marcado como respuesta Pablo RubioModerator miércoles, 20 de diciembre de 2017 15:15
-
Primero hay que averiguar CUAL es la cuenta. Esta dentro de las opciones avanzadas en las propiedades del Pool en le herramienta de configuracion de IIS.
Si es una cuenta normal de usuario, la puedes dar de alta haciendo clic-derecho en la rama "Logins" por debajo de la instancia de SQL Server en SQL Server management Studio. Si es una cuenta de sistema, no te aparecera en SSMS para seleccionarla, asi que tendras que darla de alta con un comando CREATE LOGIN en SQL Server. Recuerda que estas cuentas son distintas segun que el SQL Server sea local en la misma maquina que el IIS o que sea remoto, asi que si necesitas ayuda con esto recuerda dar suficientes detalles acerca de como es tu instalacion.
En todos los casos (tanto si la cuenta es de usuario como si es de sistema), una vez que hayas creado el Login en SQL Server hay que mapearlo a un User sobre la base de datos que estes usando. Esto si que se puede hacer graficamente en SSMS aunque la cuenta sea de sistema.
Notese que todo esto no tiene nada que ver con el hecho de que estes publicando una aplicacion web, te pasaria lo mismo si fuera cualquier otra clase de aplicacion que tuviese que acceder a un servidor de base de datos. En todos los casos seria necesario que la cuenta que ejecuta la aplicacion tuviera permisos en el servidor de base de datos, y habria que crearle el correspondiente Login y User.
- Propuesto como respuesta Pablo RubioModerator viernes, 15 de diciembre de 2017 17:23
- Marcado como respuesta Pablo RubioModerator miércoles, 20 de diciembre de 2017 15:15
-
he tomado captura de la configuración avanzada en el pool application porque no estoy seguro de donde dice cual es la cuenta:
Es donde dice "AppPoolIdentity", abajo del todo de tu captura. Si ahi haces click, te sale un botoncito a la derecha que te permite cambiar la cuenta. Esa es la cuenta que se transmite al servidor de base de datos si has configurado autenticacion integrada. Si has configurado en la cadena de conexion otro tipo de autenticacion, entonces no se usa esta cuenta, sino la que hayas puesto en la cadena.
Todo lo que te comente de mapear el Login y el Usuario se referia a SQL Server. Si no usas SQL Server, entonces no es aplicable; tendras que sustituirlo por aquello que se use en tu base de datos para autenticar y autorizar a los usuarios.
Si te funcionan bien los grids con los datos, quiere decir que estan bien puestas las credenciales tal como se usan en la cadena de conexion que empleas para traer esos datos. Asi pues, solo hay que arreglar la cadena de conexion que tengas embebida dentro del rpt para traer los datos del reporte.
- Marcado como respuesta Pablo RubioModerator miércoles, 27 de diciembre de 2017 16:45
-
la #2 y la #3 deberían funcionar, puesto que le pasas credenciales "fijas" al informe. La #1 no funcionará, porque construyes las credenciales pero no se las pasas al informe.
En última instancia, la opción #4 debe de funcionar. Puesto que ya tienes comprobado que los accesos desde código te funcionan, la carga de los datasets tiene que funcionar, y al pasárselos al informe éste no tiene que usar su propia conexión. Así que aunque sea un poco más pesado de escribir, tiene la ventaja de que nos aseguramos de que funciona (y si no funciona, al estar dentro de nuestro propio código, se puede seguir con el debugger a ver qué esta pasando).
- Marcado como respuesta Pablo RubioModerator jueves, 21 de diciembre de 2017 22:07
Todas las respuestas
-
Tiene toda la pinta de ser un problema de credenciales. El Crystal intenta abrir una conexión al servidor de base de datos para traer los datos del informe, y no lo consigue porque la cuenta bajo la que se está ejecutando (la del Pool en IIS, no la del usuario que se conecta desde el navegador) no tiene permiso de acceso al servidor de base de datos. En tiempo de desarrollo no se nota porque la cuenta bajo la que se ejecuta es la del usuario que está rodando el proyecto en Visual Studio, que sí que tiene permisos en la base de datos.
Solución: O bien cambiar la cuenta del Pool y poner una que tenga los permisos requeridos, o bien ir al servidor de base de datos y conceder permisos a la cuenta del Pool.
- Propuesto como respuesta Pablo RubioModerator viernes, 15 de diciembre de 2017 17:23
- Marcado como respuesta Pablo RubioModerator miércoles, 20 de diciembre de 2017 15:15
-
-
Primero hay que averiguar CUAL es la cuenta. Esta dentro de las opciones avanzadas en las propiedades del Pool en le herramienta de configuracion de IIS.
Si es una cuenta normal de usuario, la puedes dar de alta haciendo clic-derecho en la rama "Logins" por debajo de la instancia de SQL Server en SQL Server management Studio. Si es una cuenta de sistema, no te aparecera en SSMS para seleccionarla, asi que tendras que darla de alta con un comando CREATE LOGIN en SQL Server. Recuerda que estas cuentas son distintas segun que el SQL Server sea local en la misma maquina que el IIS o que sea remoto, asi que si necesitas ayuda con esto recuerda dar suficientes detalles acerca de como es tu instalacion.
En todos los casos (tanto si la cuenta es de usuario como si es de sistema), una vez que hayas creado el Login en SQL Server hay que mapearlo a un User sobre la base de datos que estes usando. Esto si que se puede hacer graficamente en SSMS aunque la cuenta sea de sistema.
Notese que todo esto no tiene nada que ver con el hecho de que estes publicando una aplicacion web, te pasaria lo mismo si fuera cualquier otra clase de aplicacion que tuviese que acceder a un servidor de base de datos. En todos los casos seria necesario que la cuenta que ejecuta la aplicacion tuviera permisos en el servidor de base de datos, y habria que crearle el correspondiente Login y User.
- Propuesto como respuesta Pablo RubioModerator viernes, 15 de diciembre de 2017 17:23
- Marcado como respuesta Pablo RubioModerator miércoles, 20 de diciembre de 2017 15:15
-
hola
en el codigo que muestras no veo que asignes a ninguna lado el coninfo para que defines este sino lo utilizas?
saludos
Leandro Tuttini
Blog
MVP Profile
Buenos Aires
Argentina- Propuesto como respuesta Pablo RubioModerator lunes, 18 de diciembre de 2017 15:35
-
-
Saludos y disculpa por tardar para responder pero desde la ultima respuesta hoy es que tengo acceso al servidor, no uso SSMS, uso Navicat con MySQL pero revise los privilegios de los usuarios y considero que todo esta bien
También he tomado captura de la configuración avanzada en el pool application porque no estoy seguro de donde dice cual es la cuenta:
Para finalizar no se exactamente a que te refieres con que debo mapearlo o mejor dicho no se como hacerlo. Disculpa pero soy nuevo usando el IIS y creando paginas web. Aun asi algo que habia pensado es que quizas no tenga que ver con la base de datos porque al publicar la pagina los grid traen los datos normalmente y el programa graba edita y hace todo sin problemas.
De antemano gracias por su respuesta.
-
Otra cosa que me resulta extraño es que antes si funcionaba y de repente dejo de funcionar, ademas de eso, cuando abro el reporte con el parametro que esta por defecto la primera vez abre pero si elijo otro no abre ni el que tiene parametro por defecto
-
he tomado captura de la configuración avanzada en el pool application porque no estoy seguro de donde dice cual es la cuenta:
Es donde dice "AppPoolIdentity", abajo del todo de tu captura. Si ahi haces click, te sale un botoncito a la derecha que te permite cambiar la cuenta. Esa es la cuenta que se transmite al servidor de base de datos si has configurado autenticacion integrada. Si has configurado en la cadena de conexion otro tipo de autenticacion, entonces no se usa esta cuenta, sino la que hayas puesto en la cadena.
Todo lo que te comente de mapear el Login y el Usuario se referia a SQL Server. Si no usas SQL Server, entonces no es aplicable; tendras que sustituirlo por aquello que se use en tu base de datos para autenticar y autorizar a los usuarios.
Si te funcionan bien los grids con los datos, quiere decir que estan bien puestas las credenciales tal como se usan en la cadena de conexion que empleas para traer esos datos. Asi pues, solo hay que arreglar la cadena de conexion que tengas embebida dentro del rpt para traer los datos del reporte.
- Marcado como respuesta Pablo RubioModerator miércoles, 27 de diciembre de 2017 16:45
-
No deberia ser la cadena de conexion porque lo ejecuto en query y funciona bien ademas recuerda que cuando lo ejecuto del visual studio funciona bien, yo conecto el reporte internamente a través del ODBC y segun investigo esa conexion se pierde al ejecutarlo con el IIS asi que le mando la conexion por codigo como ves pero no se conecta aun asi, ahora mismo despues de algunas modificaciones me aparece otro error que dice que no se pudo conectar con la base de datos, lo he probado habilitando y deshabilitando la opcion enabledatabaselogonprompt pero si lo activo me aparece un cuadro diciendo que el informe requiere informacion adicional y me pide los datos de la conexion (server, base de datos, usuario y contraseña)
- Editado Handelsr martes, 19 de diciembre de 2017 14:27
-
... asi que le mando la conexion por codigo como ves
No, no lo veo. En el codigo que has aportado veo que configuras los datos de conexion dentro del objeto "coninfo", pero luego no se ve que ese coninfo lo uses para nada ni se lo asignes al report.
-
Muy bien, mostrare todas las maneras de como he intentado hacer que conecte por codigo, solo quiero que me digas cual seria la mejor solucion:
#1
ReportDocument reporte = new ReportDocument(); ConnectionInfo coninfo = new ConnectionInfo(); String strRutaArchivo = Server.MapPath("SW-AI-AP-002-REP01.rpt"); reporte.Load(strRutaArchivo); reporte.SetParameterValue("vContri", Session["Codcon"]); reporte.SetParameterValue("vBD", "Siafim2017"); coninfo.ServerName = "Siafim"; coninfo.DatabaseName = "siafim2017"; coninfo.UserID = "root"; coninfo.Password = "*010405"; CrystalReportViewer1.ReportSource = reporte; CrystalReportViewer1.DataBind();
#2
ReportDocument reporte = new ReportDocument(); String strRutaArchivo = Server.MapPath("SW-AI-AP-002-REP01.rpt"); reporte.Load(strRutaArchivo); CrystalReportSource2.ReportDocument.SetParameterValue("vContri", Session["Codcon"]); CrystalReportSource2.ReportDocument.SetParameterValue("vBD", "Siafim2017"); reporte.DataSourceConnections[0].SetConnection("Siafim", "Siafim2017", "root", "*010405"); CrystalReportViewer1.ReportSource = reporte; CrystalReportViewer1.DataBind();
#3
ReportDocument reporte = new ReportDocument(); String strRutaArchivo = Server.MapPath("SW-AI-AP-002-REP01.rpt"); reporte.Load(strRutaArchivo); reporte.SetParameterValue("vContri", Session["Codcon"]); reporte.SetParameterValue("vBD", "Siafim2017"); reporte.SetDatabaseLogon("root", "*010405", "Siafim", "siafim2017"); CrystalReportViewer1.ReportSource = reporte; CrystalReportViewer1.DataBind();
Por ultimo, esto lo comence a intentar hoy cuando estaba terminando de programar, el objetivo era olvidarme de tener que pasar parametros y conexion al reporte desde el codigo de C# pero no me dio tiempo de probar y el codigo resulta mas largo y toma mas tiempo. Lo que hice en resumen fue cargar los datos a un dataset y cargar el reporte desde el dataset
#4
//abre conexion MySqlConnection con = null; Datos.Conexion cn = new Datos.Conexion(); con = cn.ConexionDa(); con.Open(); //DataTable para la primera tabla DataTable dtc = new DataTable(); MySqlCommand cmdc = new MySqlCommand(); cmdc.CommandType = CommandType.Text; cmdc.CommandText = "select* from siafimcxc.tblcontribuyente where codcon =" + Session["Codcon"]; cmdc.Connection = con; cmdc.ExecuteReader(); //Llena Datatable para la segunda tabla haciendo where en vez de INNER JOIN DataTable dti = new DataTable(); MySqlCommand cmdi = new MySqlCommand(); cmdi.CommandType = CommandType.Text; cmdi.CommandText = "SELECT i.CodInmueble, i.CodCon, i.Activo, i.Tipo, (case i.Tipo when 1 then 'Vivienda Familiar' when 2 then 'Vivienda Familiar y Comercio' when 3 then 'Comercio' end) as txtTipo, i.Categoria, (select t.descripcion from siafimcxc.tblinmuebles_tipo t where t.codigo = i.categoria) as txtCat, ifnull(i.Calle, '') as calle, ifnull(i.Urbanizacion, '') as Urbanizacion, ifnull(i.Manzana, '') as Manzana, ifnull(i.Edificio, '') as Edificio, ifnull(i.Numero, '') as Numero, ifnull(i.Apto, '') as Apto, ifnull(i.Direccion, '') as Direccion, i.Ruta, (select r.descripcion from siafimcxc.tblinmuebles_ruta r where r.codigo = i.ruta) as txtRuta, CodTemp FROM siafimcxc.tblinmuebles i where siafimcxc.tblinmuebles.CodCon=" + Session["Codcon"]; cmdi.Connection = con; cmdi.ExecuteReader(); //Asignar el codigo del inmueble a la variable string codinmueble=Convert.ToString(dti.Rows[0][0]); //Llena Datatable para la tercera tabla DataTable dtt = new DataTable(); MySqlCommand cmdt = new MySqlCommand(); cmdt.CommandType = CommandType.Text; cmdt.CommandText = "SELECT t.codinmueble, t.activo, t.codtri,(select concat_ws(' - ',siafim2017.fcodingreso(codingreso), descripcion) from siafimcxc.tbltributos_reg r where r.codtri = t.codtri) as txtTri, t.codcon, t.calculado, t.frecuencia, (select f.descripcion from siafimcxc.tblfrecuencia f where f.frecuencia = t.frecuencia) as txtFrecu , t.unidad,(select u.descripcion from siafimcxc.tblunidadm u where u.unidad = t.unidad) as txtUnidad, t.tarifa,t.campocal, t.monto, CodTemp, annoini, mesini, fechaini FROM siafimcxc.tblinmuebles_tri t where t.CodCon=" + codinmueble; cmdt.Connection = con; cmdt.ExecuteReader(); //Cierra conexion con.Close(); cmdc.Connection = con; cmdi.Connection = con; cmdt.Connection = con; MySqlDataAdapter dac = new MySqlDataAdapter(cmdc); dac.Fill(dtc); MySqlDataAdapter dai = new MySqlDataAdapter(cmdi); dai.Fill(dti); MySqlDataAdapter dat = new MySqlDataAdapter(cmdt); dat.Fill(dtt); //Crea un dataset y lo llena con los 3 datatable DataSet ds = new DataSet(); ds.Tables.Add(dtc); ds.Tables.Add(dti); ds.Tables.Add(dtt); ReportDocument reporte = new ReportDocument(); String strRutaArchivo = Server.MapPath("SW-AI-AP-002-REP01.rpt"); reporte.Load(strRutaArchivo); reporte.SetDataSource(ds); CrystalReportViewer1.ReportSource = reporte; CrystalReportViewer1.DataBind();
Tan solo por todo en lo que me has Ayudado hasta ahora Alberto mereces todos los puntos del mundo, funcione o no funcione tu ayuda gracias de antemano, inmediatamente resuelva el problema marcare tu comentario como respuesta.
-
la #2 y la #3 deberían funcionar, puesto que le pasas credenciales "fijas" al informe. La #1 no funcionará, porque construyes las credenciales pero no se las pasas al informe.
En última instancia, la opción #4 debe de funcionar. Puesto que ya tienes comprobado que los accesos desde código te funcionan, la carga de los datasets tiene que funcionar, y al pasárselos al informe éste no tiene que usar su propia conexión. Así que aunque sea un poco más pesado de escribir, tiene la ventaja de que nos aseguramos de que funciona (y si no funciona, al estar dentro de nuestro propio código, se puede seguir con el debugger a ver qué esta pasando).
- Marcado como respuesta Pablo RubioModerator jueves, 21 de diciembre de 2017 22:07
-
-
No funciona, Creo que hay que configurar bien el IIS para el Crystal Reports me canse de buscar informacion y no vi ninguna convincente o quizas se intenta conectar de la conexion interna que tiene hecha el CR y no puede. De todos modos si estas dispuesto a que hablemos de manera mas personal sobre el asunto te dare mi correo, para ver si se resuelve rapido.
handelsr@hotmail.es