I have a webform with a single button and one crystal report viewer. Crystal report is based on a MS SQL stored procedure & designed using a connection that uses SQL Server authentication.
What I have noticed that, if I call the method for showing the report within the page load, my crystal repot loads perfectly. However, if I trigger the report load through the button click (Which is a must for me to accept parameters for the report at deployment) the below happens:
Crystal report parameters are prompted (Which doesn't occur when report is loaded without a postback).
After the 1st page being loaded, 2nd page navigation prompts for database login. Without providing the login details (usually the password only), cannot go ahead. This logon prompt is only applicable to 2nd page of the report.
To circumvent the situation, I created a new connection with integrated security & postback stopped asking for the parameters and database login. Unfortunately, I cannot use integrated security for deploying the application & pry for a proper solution or workaround.
Fearing the worst, I already have RDLC report designed with the same requirements, however, I see that I have better formatting options like drawing lines over the sub reports to split columns when Crystal Report is used.
Here is what I have I tried until now
ASP page
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="c2.aspx.cs" Inherits="CrystalTest.c2" %>
<%# Register Assembly="CrystalDecisions.Web, Version=13.0.4000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" Namespace="CrystalDecisions.Web" TagPrefix="CR" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Show Report" OnClick="Button1_Click" />
<CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server" AutoDataBind="False" GroupTreeImagesFolderUrl="" Height="1202px" ReportSourceID="CrystalReportSource1" ToolbarImagesFolderUrl="" ToolPanelView="None" ToolPanelWidth="200px" Width="1104px" />
</div>
</form>
</body>
</html>
Code behind
using CrystalDecisions.CrystalReports.Engine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CrystalTest
{
public partial class c2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//ShowReport();
}
private void ShowReport()
{
ReportDocument oRpt = new ReportDocument();
oRpt.Load(Server.MapPath(#"~/CrystalReport2.rpt"));
oRpt.SetParameterValue(0, 2020);
oRpt.SetParameterValue(1, 1);
oRpt.SetParameterValue(2, "3");
oRpt.SetParameterValue(3, "1");
oRpt.SetParameterValue(4, "1");
CrystalReportViewer1.Visible = true;
CrystalReportViewer1.ReportSource = oRpt;
//oRpt.SetDatabaseLogon("sa", "password", "RT04", "menass");
oRpt.DataSourceConnections[0].SetConnection("RT04", "menass", true);
}
protected void Button1_Click(object sender, EventArgs e)
{
ShowReport();
}
}
}
I have referred the following threads from different websites and was able develop a simple solution.
1.https://www.c-sharpcorner.com/forums/crystal-reports-asking-for-database-login-credentials
2.https://forums.asp.net/post/1797759.aspx
All I needed was to pass the logon information back to the report viewer once after POSTBACK happens. Example as below:
ASP Page
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="c3.aspx.cs" Inherits="CrystalTest.c3" %>
<%# Register Assembly="CrystalDecisions.Web, Version=13.0.4000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" Namespace="CrystalDecisions.Web" TagPrefix="CR" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Print Button" OnClick="Button1_Click" />
<CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server" AutoDataBind="false" />
</div>
</form>
</body>
</html>
Code Behind
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using CrystalDecisions.Web;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CrystalTest
{
public partial class c3 : System.Web.UI.Page
{
public ReportDocument oRpt;
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
ConnectionInfo myConnectionInfo = new ConnectionInfo();
myConnectionInfo.ServerName = "RT04";
myConnectionInfo.DatabaseName = "MenaSS";
myConnectionInfo.UserID = "sa";
myConnectionInfo.Password = "password";
SetdblogonforReport(myConnectionInfo);
}
}
private void SetdblogonforReport(ConnectionInfo myConnectionInfo)
{
//throw new NotImplementedException
TableLogOnInfos mytableloginfos = new TableLogOnInfos();
mytableloginfos = CrystalReportViewer1.LogOnInfo;
foreach (TableLogOnInfo myTableLogOnInfo in mytableloginfos)
{
myTableLogOnInfo.ConnectionInfo = myConnectionInfo;
}
}
private void ShowReport()
{
if (!IsPostBack | Session["Report"] == (default))
{
oRpt = new ReportDocument();
oRpt.Load(Server.MapPath(#"~/CrystalReport2.rpt"));
oRpt.SetParameterValue(0, 2020);
oRpt.SetParameterValue(1, 1);
oRpt.SetParameterValue(2, "9");
oRpt.SetParameterValue(3, "1");
oRpt.SetParameterValue(4, "1");
Session.Add("Report", oRpt);
}
else
{
oRpt = (ReportDocument)Session["Report"];
}
CrystalReportViewer1.ReportSource = oRpt;
oRpt.SetDatabaseLogon("sa", "password", "RT04", "menass");
}
protected void Button1_Click(object sender, EventArgs e)
{
ShowReport();
}
}
}
This solution is good enough for sub reports also, as all the authentications are taken care by the single logon call using the method SetdblogonforReport.
Hope this helps few others out there.
I've a better solution & not deleting the previous one because it does deal with the postback when page_load method is present in a page. The below answer (which is recommended by SAP) is the one I am currently using for my project.
Resolving this requirement using "Session" and "page_init" as suggested. Please note, my application need to collect many inputs from the end user before generating the report & many of the text inputs have Autopostback set as true. Everytime the autopostback happens, Crystal Report refreshes, hence I recommend using as less possible Autopostback enabled input fields with your web form.
Sample ASP page
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="c4.aspx.cs" Inherits="CrystalTest.c4" %>
<%# Register Assembly="CrystalDecisions.Web, Version=13.0.4000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" Namespace="CrystalDecisions.Web" TagPrefix="CR" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Print Report" OnClick="Button1_Click" />
<CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server" AutoDataBind="true" />
</div>
</form>
</body>
</html>
and the code behind (copied from a crude test form, please make sure that you follow the coding standards recommended). Please note, this sample doesn't have "page_load" method, hence if you have specific situations where page_load is required, you will have to adapt much tedious approaches or clicking the button to generate the report should be redirected to a page where you have only the report.
using CrystalDecisions.CrystalReports.Engine;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CrystalTest
{
public partial class c4 : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
if (IsPostBack)
{
CrystalReportViewer1.ReportSource = (ReportDocument)Session["Report"];
}
}
private void ShowReport1()
{
string ConnectionString = ConfigurationManager.ConnectionStrings["menass"].ToString();
using (SqlConnection con = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("GETMONTHSALARY", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#pProcessYear", SqlDbType.Int).Value = 2020;
cmd.Parameters.Add("#pProcessMonth", SqlDbType.Int).Value = 1;
cmd.Parameters.Add("#pProcessSection", SqlDbType.VarChar).Value = "9";
cmd.Parameters.Add("#pProcessSite", SqlDbType.VarChar).Value = "1";
cmd.Parameters.Add("#pProcessCatg", SqlDbType.VarChar).Value = "1";
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds, "SalaryDT");
ReportDocument oRpt = new ReportDocument();
oRpt.Load(Server.MapPath(#"~/dataset/CrystalReport1.rpt"));
oRpt.DataSourceConnections.Clear();
oRpt.SetDataSource(ds);
oRpt.Subreports[0].SetDataSource(FillOverTime());
CrystalReportViewer1.Visible = true;
CrystalReportViewer1.ReportSource = oRpt;
Session["Report"] = oRpt;
}
}
}
private DataSet FillOverTime()
{
string ConnectionString = ConfigurationManager.ConnectionStrings["menass"].ToString();
using (SqlConnection con = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("GetEmployeeOverTime", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#pEmployeeCode", SqlDbType.VarChar).Value = DBNull.Value;
cmd.Parameters.Add("#pProcessYear", SqlDbType.Int).Value = 2020;
cmd.Parameters.Add("#pProcessMonth", SqlDbType.Int).Value = 1;
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds1 = new DataSet();
adapter.Fill(ds1, "OverTimeDT");
return ds1;
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
ShowReport1();
}
}
}
I'm trying to insert simple data in mysql database on a button click but whenever I try to do so, the button click is processed but the data is not getting inserted and also there are no exceptions or errors. I have the database stored in my localhost with exact same table name and column name yet it is creating the problem. Don't know the issue seems to be.
testing.aspx file
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="testing.aspx.cs" Inherits="CricketAnalysis2.testing" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<p>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
</p>
</form>
</body>
</html>
testing.aspx.cs file
using System;
using MySql.Data.MySqlClient;
using System.Data;
namespace CricketAnalysis2
{
public partial class testing : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
MySqlConnection con = new MySqlConnection(#"Data Source=localhost;port=3306;Initial Catalog=cricdb;User Id=root;password=''");
con.Open();
MySqlCommand cmd1 = con.CreateCommand();
cmd1.CommandType = CommandType.Text;
cmd1.CommandText = "INSERT INTO drug VALUES ('"+TextBox1.Text+"')";
con.Close();
}
}
}
The issue is you're not executing the command. You need to call ExecuteNonQuery() method so:
cmd1.ExecuteNonQuery();
Furthermore, your query is currently open to sql injection, to avoid that you should use paramertised queries and also make use of using block to ensure the object is disposed correctly.
var connectionString = "Data Source=localhost;port=3306;Initial Catalog=cricdb;User Id=root;password=''\"";
var query = "INSERT INTO DRUG VALUES(#ParameterName)";
using (var con = new MySqlConnection(connectionString))
{
using (var cmd = new MySqlCommand(query, con))
{
cmd.Parameters.Add("#ParameterName", MySqlDbType.VarChar).Value = TextBox1.Text;
con.Open();
cmd.ExecuteNonQuery();
}
}
I am trying to display data in Gridview in c#. I have been asked to make the gridview look as close as a table in SQL database. I have been able to achieve a bit but my grid is far from a Sql table. Can someone help me out? This is what I tried so far.
Aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Reports.aspx.cs" Inherits="Reports" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Enter Query"></asp:Label> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</div>
<p>
<asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click" />
<div id="grdCharges" runat="server" style="width: 875px; overflow: auto; height: 600px;">
<asp:GridView ID="grd1" runat="server" AutoGenerateColumns="true" Width="150%">
</asp:GridView>
</div>
</p>
</form>
</body>
</html>
C#
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Reports : System.Web.UI.Page
{
protected void Button1_Click(object sender, EventArgs e)
{
SqlConnection con = null;
SqlDataReader reader = null;
try
{
string q = TextBox1.Text.ToString();
string strcon = "Data Source=***********";
con = new SqlConnection(strcon);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = q;
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
con.Open();
reader = cmd.ExecuteReader();
// Data is accessible through the DataReader object here.
var dataTable = new DataTable();
dataTable.Load(reader);
grd1.DataSource = dataTable;
grd1.DataBind();
}
catch (Exception ex)
{
//....
}
finally
{
if(reader != null)
reader.Close();
if(con != null && con.ConnectionState != ConnectionState.Closed)
con.Close();
}
}
}
This is how my table looks like -
Current table -
Current table
Target table -
Targettable
I am trying to autocomplete textbox, and i downloaded source code from any website,
Here is aspx page code
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Ajax AutoCompleteExtender without Webservice</title>
</head>
<body>
<form id="form1" runat="server">
<ajax:ToolkitScriptManager ID="ScriptManager1" runat="server"/>
<div>
<asp:TextBox ID="txtCountry" runat="server"></asp:TextBox>
<ajax:AutoCompleteExtender ID="AutoCompleteExtender1" runat="server"
TargetControlID="txtCountry"
MinimumPrefixLength="1" EnableCaching="true" CompletionSetCount="1"
CompletionInterval="1000" ServiceMethod="GetCountries" >
</ajax:AutoCompleteExtender>
</div>
</form>
and here is codebehind file.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[System.Web.Script.Services.ScriptMethod()]
[System.Web.Services.WebMethod]
public static List<string> GetCountries(string prefixText)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnection"].ToString());
con.Open();
SqlCommand cmd = new SqlCommand("select varStateName from tblStateMaster where varStateName like #Name'%'", con);
cmd.Parameters.AddWithValue("#Name", prefixText);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
List<string> CountryNames = new List<string>();
for (int i = 0; i < dt.Rows.Count; i++)
{
CountryNames.Add(dt.Rows[i][1].ToString());
}
return CountryNames;
}
}
It could not generate proper output and i am not able to debug this service, so how can i debug such service, and please tell me where is exact problem and which points should be remember for service and autocomplete,
And one more thing can i do it with dropdownlist?
I suspect the issue is in your query and more specifically in the %, try to include it in your parameter instead:
prefixText = string.Concat(prefixText, "%");
SqlCommand cmd = new SqlCommand("select varStateName from tblStateMaster where varStateName like #Name", con);
EDIT
Ok, so digging around, according to official examples from Microsoft, your method signature should look like this (notice the additional parameters):
public static string[] GetCountries(string prefixText)
{
// your stuff
}
I have a text box, a script manager and an auto-complete extender on an aspx page. I'm trying to simply have an auto complete into the text box and am currently getting nothing. What am I missing? When I try to debug the code the break point never gets beyond the first curly brace in the GetComplete method. I'm on VS2010
markup:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="AjaxAutocomplete._Default" %>
<%# Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="asp" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:AutoCompleteExtender ID="TextBox1_AutoCompleteExtender" runat="server"
DelimiterCharacters="" Enabled="True" ServiceMethod="GetComplete" MinimumPrefixLength="3" TargetControlID="TextBox1">
</asp:AutoCompleteExtender>
</asp:Content>
code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace AjaxAutocomplete
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[System.Web.Script.Services.ScriptMethod]
[System.Web.Services.WebMethod]
public static List<string> GetComplete(string Prefixtetxt)
{
List<string> returnList = new List<string>();
string cs = ConfigurationManager.ConnectionStrings["dbcs"].ConnectionString;
using (SqlConnection conn = new SqlConnection(cs))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p = new SqlParameter("#drug_name", Prefixtetxt);
//cmd.Parameters.AddWithValue("#drug_name", p);
cmd.Parameters.Add("#drug_name", SqlDbType.VarChar);
using (SqlDataReader reader = cmd.ExecuteReader())
{
returnList.Add(Convert.ToString(reader["drug_name"]));
}
}
}
return returnList;
}
}
}
sproc from Sql Server
create proc spFindAllDrugs
#drug_name varchar(100)
as
begin
select distinct drug_name
from rx
where drug_name like '%' + #drug_name + '%'
end
It looks like you are not associating the SqlCommand with the connection or telling the command the name of your stored procedure. Try modifying your code as shown.
using (SqlCommand cmd = new SqlCommand("spFindAllDrugs"))
{
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;