How to bind DevExpress XtraReport by Query String - sql

Can anybody tell me how I can bind a DevExpress XtraReport by Query String?
I want to show only the ID value of 8 in the report, I am using a store procedure to get data.
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["con"].ConnectionString);
SqlCommand cmd = new SqlCommand("GetLabReport", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#PID", SqlDbType.Int).Value = Request.QueryString["ID"].ToString();
connection.Open();
SqlDataAdapter DA = new SqlDataAdapter(cmd);
DataTable DT = new DataTable();
XtraReport1 Rept = new XtraReport1();
string path = (Server.MapPath("App_Code/XtraReport1.cs"));
DA.Fill(DT);
connection.Close();
if(DT.Rows.Count>0)
{
}
The above works fine with Crystal Reports but not with DevExpress XtraReports.

I suggest you to create report parameters and then set the parameter value using the query string.
See the comments on below thread:
Report Designer using SQL Server Stored Procedure as data source, generates .Net exception.
Add a Report's Parameters and then map it to your query parameter. Then pass the value from Request.QueryString to the Parameter.Value property
Example:
protected void Page_Load(object sender, EventArgs e) {
XtraReport3 report = new XtraReport3();
report.Parameters[0].Value = Request["MyParam"];
ASPxDocumentViewer1.Report = report;
}
References:
Passing querystring values to a report
How to use parameter from querystring to show report
Parameters support thru URL QueryString in XtraReports?
How to pass QueryString parameter into Report (master-detail) c#

Related

How to deal with this SQL injection warning (CA2100)

Below is the code I got from Microsoft page: SqlCommand
public static Int32 ExecuteNonQuery(String connectionString, String commandText, CommandType commandType, params SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(commandText, conn))
{
// There're three command types: StoredProcedure, Text, TableDirect. The TableDirect
// type is only for OLE DB.
cmd.CommandType = commandType;
cmd.Parameters.AddRange(parameters);
conn.Open();
return cmd.ExecuteNonQuery();
}
}
}
However, VS code analysis still complains about "CA2100":
Warning CA2100 The query string passed to 'SqlCommand.SqlCommand(string, SqlConnection)' in 'FlexClaimFormRepository.ExecuteNonQuery(string, string, CommandType, params SqlParameter[])' could contain the following variables 'commandText'. If any of these variables could come from user input, consider using a stored procedure or a parameterized SQL query instead of building the query with string concatenations.
I know the exact reason why the warning is there, but anyidea on how to get rid of it? Given setting commandText inside the function is not acceptable since I want it to be a parameter.
I know this question is old, but maybe this will help someone with the same issue. I also was using a stored procedure and therefore suppressed the warning using the information from this article from Microsoft:
https://learn.microsoft.com/en-us/visualstudio/code-quality/in-source-suppression-overview?view=vs-2019 .
Here's the attribute I added to my method:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Security", "CA2100:Review SQL queries for security vulnerabilities", Justification = "Method already uses a Stored Procedure")]

SqlDataSource lost the where clause during paging

I have a SqlDataSource with this query:
SELECT [ProductName], [Debscription], [Price] FROM [MyDb] WHERE ([Date1] >= #Date1) ORDER BY [ProductName]">
When I load the page, it works fine and shows me only the products that I want.
When I try changing page of the GridView, and for example, go to page 2, it refreshes the page and generates lots of page indexes as the where clause is lost.
How can I solve this?
I thought that the statement was automatically saved, but it's not.
How can I save the where clause during paging?
For dynamic paging you should use an ObjectDataSource instead of a SqlDataSource.
If you want the grid to handle paging, bind it to a DataTable or DataSet. For ex:
private void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
BindData();
}
private void BindData()
{
// Connect to the Database
SqlConnection myConnection = new SqlConnection(connection string);
// Retrieve the SQL query results and bind it to the DataGrid
string SQL_QUERY = "SELECT ProductName, UnitPrice, UnitsInStock " +
"FROM Products";
SqlCommand myCommand = new SqlCommand(SQL_QUERY, myConnection);
// Use a DataTable – required for default paging
SqlDataAdapter myAdapter = new SqlDataAdapter(myCommand);
DataTable myTable = new DataTable();
myAdapter.Fill(myTable);
dgProducts.DataSource = myTable;
dgProducts.DataBind();
myConnection.Close();
}
https://msdn.microsoft.com/en-us/library/aa479006.aspx

Getting SQL error while reading the data

SqlCommand cmd = new SqlCommand("SELECT * FROM Products",con);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (reader["ProductName"].ToString() == "dsd")
{
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Products", con);
DataSet ds = new DataSet();
da.Fill(ds);
ListView1.DataSource = ds;
ListView1.DataBind();
}
}
reader.Close();
Error :
Already an open DataReader associated with this Command which must be closed first
I am getting error on this line da.fill(ds). And I used two commands one SqlCommand to read the record and second SqlDataAdapter to show record.
If I understand your problem correctly, you need to bind a listview control with all the products by name "dsd".
If this is correct, you can change the SQL query like this:
SELECT * FROM Products WHERE ProductName = 'dsd'
You can read the response from the DataReader and prepare the List to bind to your listview control. I don't think you need DataSet to bind to listview control.
You need two connection objects. One for your open data reader and a second to use with the SqlDataAdapter.
(Or you can use MARS, but really it is far better to just open a second connection.)

Why calling DataTable.Clear() then DBDataAdapter.Update(DataTable) does not clear the table in database?

I try to use the code sample in DBDataAdapter.Update Method to clear a table in a database.
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM WebCam", connection);
DataTable table = new DataTable();
adapter.Fill(table);
table.PrimaryKey = new DataColumn[] { table.Columns["Date"] };
//table.Rows[0]["Date"] = System.DateTime.Now; //It's OK to modify a row
table.Clear(); //But it is not working to clear the table
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.Update(table);
}
I can add new rows or modify existing rows, and the changes can be committed to the database, but if I try to empty the table, the change to 'table' can not be committed to the database, also, no exception is thrown.
Do I miss something?
u should get error on this line:
table.PrimaryKey = new DataColumn[] { table.Columns["Date"] };
this would mean that u have catched the exception somewhere else, maybe from where the function is being called, and not showing the error in a messege box.
Another reason might be because you are using words like Table, adapter etc ... my guess is that you might be overloading some reserved words functionalities.

Reading and Updating Data Using SqlDataAdapter Question

I'm looking for some examples on how to best use SqlDataAdapter to access and update data in my application.
Right now I have something like this:
SqlDataAdapter adapter;
DataSet myData = MyDataAccessClass.GetData("Select * from Students", ref adapter);
// change some data here and save changes
adapter.Update();
All of this occurs in code behind, and I dont really like it at all.
So, I'm trying to find a way to do something like this:
DataSet myData = MyDataAccessClass.GetStudents();
// change some data and save changes
MyDataAccessClass.SaveStudents(myData);
Where SaveStudents method still uses SqlDataAdapter to update db.
Any ideas on how to make this work or some pointers to best practices of doing
something like this are highly appreciated. Thank you.
That seems like a fairly basic Data Access Layer implementation, to me. Generally, I do it something like this:
public class MyDataAccessClass
{
private string ConnString;
public MyDataAccessClass()
{ //Get connection string from configuration file }
public MyDataAccessClass(string connString)
{ ConnString = connString; }
public DataSet GetAllStudents()
{
//your SQL Adapter code here...
}
}
One note that I'd make is that with so many ORM solutions (including just Entity Framework and Linq2Sql) available, you may want to consider using collections of objects instead of data-sets for your Data Representations. Then you can have a method like:
public void CreateUpdateStudent(Student student)
{
//update database
}
That's fairly subjective, I'll admit, but I find it preferable to using straight DataSets.
If you want to get update data using the sql-data-adapter then you could use these
Using System.Data.SqlClient;
SqlConnection con = new SqlConnection("Data Source=abcd-pc;Initial Catalog=user_info;Integrated Security=True");
SqlDataAdapter da = new SqlDataAdapter();
try
{
da.UpdateCommand = new SqlCommand("Update logindemo set password=#pswd where username=#uname",con);
da.UpdateCommand.Parameters.Add("#pswd", SqlDbType.VarChar).Value = txtpass.Text;
da.UpdateCommand.Parameters.Add("#uname", SqlDbType.VarChar).Value = txtusername.Text;
con.Open();
da.UpdateCommand.ExecuteNonQuery();
Label1.Text = "Data Updated";
con.Close();
}
catch
{
Label1.Text = "Unable To Connect";
}
I hope you understand how to update the data easily. It just like the example. You can use these type of example in Inserting into the Data, and Deleting the Data with using specific the command and sql query as it required.