Dataaccess help in three tier asp.net architecture - asp.net

I have DAL function as
public DataTable executeSelectQuery(String _query, SqlParameter[] sqlParameter)
{
SqlCommand myCommand = new SqlCommand();
DataTable dataTable = new DataTable();
dataTable = null;
DataSet ds = new DataSet();
try
{
myCommand.Connection = openConnection();
myCommand.CommandText = _query;
myCommand.Parameters.AddRange(sqlParameter);
myCommand.ExecuteNonQuery();
myAdapter.SelectCommand = myCommand;
myAdapter.Fill(ds);
dataTable = ds.Tables[0];
}
catch (SqlException e)
{
Console.Write("Error - Connection.executeSelectQuery - Query:
" + _query + " \nException: " + e.StackTrace.ToString());
return null;
}
finally
{
}
return dataTable;
}
My button click
public void save_click(object sender,EventArgs e)
{
try
{
string query = "Insert into customer_master(customer_title,customer_name)values(#parameter1,#parameter2)";
SqlParameter[] sqlparam = new SqlParameter[2];
sqlparam[0] = new SqlParameter("#parameter1", SqlDbType.VarChar, 50);
sqlparam[0].Value = ddl_title.SelectedValue;
sqlparam[1] = new SqlParameter("#parameter2", SqlDbType.VarChar, 50);
sqlparam[1].Value = txt_group_name.Text;
string id = ms.insert(query, sqlparam);
catch(Exception ex)
{
throw ex;
}
}
I want the button click function values to passed not as sqlparameter but as sql command object.How to do this with sqlcommand object instead of sqlparameter.

Why do you want to pass around SqlCommand objects?? I wouldn't consider that an improvement of your current code - in the contrary!
Your UI code should really only pass values to the DAL function - just a List<int> or two strings or something. The DAL should do all the database-related stuff like creating SqlCommand and SqlParameters
So in your case here, I would have a method InsertCustomer on your DAL something like this:
public void InsertCustomer(string customerName, string customerTitle)
{
.... // do all the DB stuff here - create SqlCommand, fill in SqlParameter,
// execute the query
}
and your UI code should call this like this:
MyDAL dal = new MyDAL();
dal.InsertCustomer(txt_group_name.Text, ddl_title.SelectedValue);
There should be no trace whatsoever of ADO.NET classes or function in your UI code layer! So don't create SqlCommand or even SqlParameter in your UI layer - encapsulate this in the DAL layer! That what it's for!

Related

How to fix checkmarx stored XSS issue from datatable gridData binding

Below is the code for retrieving datatable from database
protected DataTable ExecuteDataTableSQL(string strSQL)
{
using (OracleConnection connection = new OracleConnection(_strConnectionString))
{
dbAdapter.SelectCommand.Connection = connection;
connection.Open();
DataTable dtResult = new DataTable();
try
{
OracleCommand comm = dbAdapter.SelectCommand;
comm.CommandText = strSQL;
comm.CommandType = CommandType.Text;
dbAdapter.Fill(dtResult);
}
catch (Exception ex)
{
throw (ex);
}
return dtResult;
}
}
Below is the simplified code I am using the above method
DataTable dtResult = new DataTable();
string strSQL="some select statement";
dtResult = ExecuteDataTableSQL(strSQL);
if (dtResult.Rows.Count > 0)
{
DataGrid dg = new DataGrid();
dg.DataSource = dtResult;
dg.DataBind();
}
Checkmarx reports this as stored XSS as gets data from the database, for the dtResult element. This element’s value then flows through the code without being properly filtered or encoded and is eventually displayed to the user in method
source: dbAdapter.Fill(dtResult);
destination: dg.DataSource = dtResult;
How to resolve the issue.

Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack when I use scope identity

Here is ehat I try to do
on button_click I read the values from the text boxes and insert them in them in the database.
as tourist number for example maybe two or three tourists with ExecuteScalar; i get the ids of teh tourists which are inserted!
public void cmdInsert_OnClick(object sender, EventArgs e)
{
if (Page.IsValid)
{
string numtourist = (string)Session["tourist_number"];
for (int i = 0; i < Int32.Parse(numtourist); i++)
{
TextBox tx888 = (TextBox)FindControl("txtNameK" + i.ToString());
TextBox tx888_1 = (TextBox)FindControl("txtMidNameK" + i.ToString());
TextBox tx888_2 = (TextBox)FindControl("txtLastNameK" + i.ToString());
string insertSQL = "INSERT INTO Tourist (Excursion_ID, Excursion_date_ID, Name_kir,Midname_kir, Lastname_kir)";
insertSQL += " VALUES (#Excursion_ID, #Excursion_date_ID, #Name_kir,#Midname_kir, #Lastname_kir) SELECT ##IDENTITY";
string connectionString = "Data Source = localhost\\SQLExpress;Initial Catalog=excursion;Integrated Security=SSPI";
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(insertSQL, con);
cmd.Parameters.AddWithValue("#Excursion_ID", Convert.ToInt32(mynew2));
cmd.Parameters.AddWithValue("#Excursion_date_ID", Convert.ToInt32(mynewnewstring));
cmd.Parameters.AddWithValue("#Name_kir", tx888.Text);
cmd.Parameters.AddWithValue("#MidName_kir", tx888_1.Text);
cmd.Parameters.AddWithValue("#LastName_kir", tx888_2.Text);
int added;
try
{
con.Open();
added = (int)cmd.ExecuteScalar();
lblproba.Text = "";
Tourist.Add(added);
lblproba.Text += Tourist.Count();
}
catch (Exception ex)
{
lblproba.Text += ex.Message;
}
finally
{
con.Close();
}
}
createReservation();
}
}
I call CreateReservationFunction AND i CREATE A NEW RESERVAION WITH THE ID OF THE USER WHO HAS MADE THE RESERVATION. wITH SELECT IDENTITY I TRY TO GET THE RESERVATION_ID of the reservation and here I get the exception "Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack". So I wonder can this exception has something commn with the fact that in my solution exceptthe asp.net web projectI got library class in which I has .edmx file The entity framework model of my database and in my last form I don't use Ado,net but Entity framework
public void createReservation()
{
string insertSQL = "Insert INTO RESERVATIONS (User_ID) values (#User_ID) SELECT ##IDENTITY";
string connectionString = "Data Source = localhost\\SQLExpress;Initial Catalog=excursion;Integrated Security=SSPI";
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(insertSQL, con);
cmd.Parameters.AddWithValue("#User_ID", 9);
try
{
con.Open();
string added = cmd.ExecuteScalar().ToString();
createTouristReservation(added);
}
catch (Exception ex)
{
lblproba.Text+= ex.Message;
}
}
Don't use ##IDENTITY but SCOPE_IDENTITY and add a semicolon between the insert and the select.
string insertSQL = #"INSERT INTO Tourist (Excursion_ID, Excursion_date_ID, Name_kir,Midname_kir, Lastname_kir)
VALUES (#Excursion_ID, #Excursion_date_ID, #Name_kir,#Midname_kir, #Lastname_kir)
;SELECT CAST(scope_identity() AS int)";

Asp.net markup file

I have been given some c# code and have been asked to create a markup (.aspx) file that would go along with it.
I am not asking for help to write the code, but instead, how to go about it.
Here is the code:
public partial class search : Page
{
protected override void OnLoad(EventArgs e)
{
int defaultCategory;
try
{
defaultCategory = Int32.Parse(Request.QueryString["CategoryId"]);
}
catch (Exception ex)
{
defaultCategory = -1;
}
Results.DataSource = GetResults(defaultCategory);
Results.DataBind();
if (!Page.IsPostBack)
{
CategoryList.DataSource = GetCategories();
CategoryList.DataTextField = "Name";
CategoryList.DataValueField = "Id";
CategoryList.DataBind();
CategoryList.Items.Insert(0, new ListItem("All", "-1"));
CategoryList.SelectedIndex = CategoryList.Items.IndexOf(CategoryList.Items.FindByValue(defaultCategory.ToString()));
base.OnLoad(e);
}
}
private void Search_Click(object sender, EventArgs e)
{
Results.DataSource = GetResults(Convert.ToInt32(CategoryList.SelectedValue));
Results.DataBind();
}
private DataTable GetCategories()
{
if (Cache["AllCategories"] != null)
{
return (DataTable) Cache["AllCategories"];
}
SqlConnection connection = new SqlConnection("Data Source=DB;Initial Catalog=Store;User Id=User;Password=PW;");
string sql = string.Format("SELECT * From Categories");
SqlCommand command = new SqlCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
Cache.Insert("AllCategories", dt, null, DateTime.Now.AddHours(1), System.Web.Caching.Cache.NoSlidingExpiration);
connection.Dispose();
return dt;
}
private DataTable GetResults(int categoryId)
{
SqlConnection connection = new SqlConnection("Data Source=DB;Initial Catalog=Store;User Id=User;Password=PW;");
string sql = string.Format("SELECT * FROM Products P INNER JOIN Categories C on P.CategoryId = C.Id WHERE C.Id = {0} OR {0} = -1", categoryId);
SqlCommand command = new SqlCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
connection.Dispose();
return dt;
}
}
EDIT
In the above code, what is the Results object and is the CategoryList just a listbox?
As Nilesh said this seems like a search page, You can possibly try creating the a Webform using Visual studio which is just drag and drop controls into canvas and that will create the mark up for the controls in the code window.
This code behind seems to be doing the following,
On page load at Get request (when its !Page.IsPostBack) page is going to get categories using GetCategories() and fill the drop down list "CategoryList" with all category names (default selected one being the defaultcategory ID from query string).
The search button takes the dropdown's selected value and calls the GetResults() to get data table to fill the grid view "Results". So you need 3 controls (Dropdown list, Button, Gridview) in the webform with these names..

data source does not support server-side data paging

i am currently trying to do paging for my gridview but once i allow paging in my gridview it will give me this error : The data source does not support server-side data paging.
this is my code for gridview :
SqlDataReader reader = cmd.ExecuteReader();
GridView1.DataSource = reader;
GridView1.DataSourceID = null;
GridView1.Visible = true;
GridView1.AllowPaging= true;
GridView1.DataBind();
conn.Close();
SqlDataReader is forward-only. Server-side Paging needs to be able to traverse the datasource both backward and forward. Use a different datasource, like SqlDataAdapter, which supports bi-directional traversal.
Example (as requested):
string query = string.Empty;
SqlConnection conn = null;
SqlCommand cmd = null;
SqlDataAdapter da = null;
DataSet ds = null;
try {
query = "SELECT * FROM table WHERE field = #value";
conn = new SqlConnection("your connection string");
cmd = new SqlCommand(query, conn);
cmd.Parameters.Add("value", SqlDbType.VarChar, 50).Value = "some value";
da = new SqlDataAdapter(cmd);
ds = new DataSet();
da.Fill(ds);
if (ds.Tables.Count > 0) {
GridView1.DataSource = ds.Tables(0);
GridView1.AllowPaging = true;
GridView1.DataBind();
}
} catch (SqlException ex) {
//handle exception
} catch (Exception ex) {
//handle exception
} finally {
if (da != null) {
da.Dispose();
}
if (cmd != null) {
cmd.Dispose();
}
if (conn != null) {
conn.Dispose();
}
}
SqlDataAdapter is also from the System.Data.SqlClient Namespace.
Have you tried using a SqlDataAdapter to fill a DataSet/DataTable with your SQL results? Then use that DataTable as your data source for the GridView. Basic framework for filling your DataTable:
public DataTable GetDataTable(String connectionString, String query)
{
DataTable dataTable = new DataTable();
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))
{
dataAdapter.Fill(dataTable);
}
}
}
}
catch
{
}
return dataTable;
}
And then you can use that DataTable as your GridView DataSource:
String connectionString = "Data Source=<datasource>;Initial Catalog=<catalog>;User Id=<userID>;Password=<password>;";
String query = "SELECT * FROM TABLE_NAME WHERE ID=BLAH";
GridView1.DataSource = GetDataTable(connectionString, query);
GridView1.DataSourceID = null;
GridView1.Visible = true;
GridView1.AllowPaging= true;
GridView1.DataBind();
Hopefully this will help.
You can apply paging to a gridview in two ways
(1) Use an object datasource with your gridview
(2) Use jquery Datatable

Data rows from database are not displayed in rdlc report

This is my code`
protected void btnCreateBill_Click(object sender, EventArgs e)
{
DisplayReport();
}
private DataTable TotalInfoData()
{
try
{
// Open Sql Connection
SqlConnection SqlCon = new SqlConnection(#"Data Source=PRATIKPC;Initial Catalog=dbbilling2.0;Integrated Security=True");
SqlCon.Open();
// Create a Command
SqlCommand SqlComm = new SqlCommand();
SqlComm.Connection = SqlCon;
SqlComm.CommandType = CommandType.Text;
SqlComm.CommandText = "select * from tblTotalFee where Class='" + ClassDropDownList.SelectedItem.Value + "'and StudentID='" + StudentNameDropDownList.SelectedItem.Value+"'";
// Create instance of Northwind DataSetXSD
DataSet1.tblTotalFeeDataTable TotalInfoData = new DataSet1.tblTotalFeeDataTable();
// Set a Data Commands
SqlDataAdapter SqlDa = new SqlDataAdapter(SqlComm);
SqlDa.Fill(TotalInfoData); // Fill Data in NorthwindDataSet Object.
return TotalInfoData;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
private void DisplayReport()
{
try
{
// Clear the Data Source
ReportingForPrintingReportViewer.LocalReport.DataSources.Clear();
// Set a DataSource to the report
// First Parameter - Report DataSet Name
// Second Parameter - DataSource Object i.e DataTable
ReportingForPrintingReportViewer.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", TotalInfoData()));
// OR Set Report Path
ReportingForPrintingReportViewer.LocalReport.ReportPath = HttpContext.Current.Server.MapPath("~/Report.rdlc");
// Refresh and Display Report
ReportingForPrintingReportViewer.LocalReport.Refresh();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
Why isn't any output coming in report?? There are rows in my database but it has not been returned. My report looks like this after the operation. Why aren't rows being displayed??
This is my dataset
Try adding the schema name before the dataset name. Like- SchemaName_DataSet1.
ReportingForPrintingReportViewer.LocalReport.DataSources.Add(new ReportDataSource("SchemaName_DataSet1", TotalInfoData()));

Resources