In my web application there is a WCF web service. In the following method
public string GetPolicyDetails(GetPolicyDetails_ML ml)
{
var strFileName = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"log.xml");
DataTable dt = new DataTable();
DataSet ds = new DataSet();
try
{
con = new SqlConnection(connectionString);
con.Open();
cmd = new SqlCommand("sp_GetPolicyDetails", con) { CommandType = CommandType.StoredProcedure };
cmd.Parameters.AddWithValue("#policy_id", ml.policyID);
adp = new SqlDataAdapter(cmd);
adp.Fill(dt);
string json = JsonConvert.SerializeObject(dt,Formatting.Indented);
return json;
}
catch (SqlException ex)
{
return "fail";
}
finally
{
con.Close();
con.Dispose();
}
}
will return a json string inWCF Test Client. I need to access this method from my tab application. The code i used is
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
var ds = await client.GetPolicyInfoAsync(Convert.ToInt16(txtPolicyNumber.Text));
This will get the response in to the #var ds#. My question is what is the type of this var ds and how to get the Json data out of this variable ds. Thanks in advance.
Related
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.
I created web API using dotNet. It work but i got a little problem.
This is my controller
WaybillDataAccessLayer objway = new WaybillDataAccessLayer();
public IEnumerable<Waybill> Get(string id_wb)
{
List<Waybill> lstWaybill = new List<Waybill>();
lstWaybill = objway.GetWaybill(id_wb).ToList();
return lstWaybill;
}
and my Models(WaybillDataAccessLayer)
public IEnumerable<Waybill> GetWaybill(String id_wb)
{
List<Waybill> lswaybill = new List<Waybill>();
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("spGetWaybill", con); //Stored procedure on database
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#waybill", id_wb);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read()) //foreach
{
Waybill wb = new Waybill();
wb.waybill = rdr["waybill"].ToString();
wb.deskripsi = rdr["deskripsi"].ToString();
wb.tanggal = rdr["tanggal"].ToString();
wb.pengirim = rdr["pengirim"].ToString();
wb.lokasi = rdr["lokasi"].ToString();
wb.penerima = rdr["penerima"].ToString();
lswaybill.Add(wb);
}
con.Close();
}
return lswaybill;
}
when i run this API,the output will be like this
[
{
"waybill": "00000093",
"deskripsi": "SPARE PARTS",
"tanggal": "19990727",
"pengirim": "JIEP",
"lokasi": "HO",
"penerima": "JKHO"
}
]
My Question is
how to remove that [] ?
how to add another information like
{
"status" : "sucess",
"data" { }
}
Thankyou for your help.
You're returning a list of WayBill objects. If you don't want the resulting JSON to be an array, then you need to just return a single WayBill, not a List. And if you want to wrap that in more data, then create a type to represent that information, populate an instance of it, and return it.
Since you're retrieving these objects by ID, I'm assuming there should be only one WayBill for any given ID. Thus you can simplify your data access layer.
public Waybill GetWaybill(String id_wb)
{
using (SqlConnection con = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("spGetWaybill", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#waybill", id_wb);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();
Waybill wb = new Waybill();
wb.waybill = rdr["waybill"].ToString();
wb.deskripsi = rdr["deskripsi"].ToString();
wb.tanggal = rdr["tanggal"].ToString();
wb.pengirim = rdr["pengirim"].ToString();
wb.lokasi = rdr["lokasi"].ToString();
wb.penerima = rdr["penerima"].ToString();
return wb;
}
}
And add the type to wrap your response:
class GetWayBillResponse()
{
public string Status { get; set;}
public WayBill WayBill { get; set; }
}
Note that adding a status here isn't really all that helpful if you're seeing the object, you can assume it was successful. Also, the API would have responded with an HTTP 200 OK status code. So it's really superfluous.
Now your controller becomes:
WaybillDataAccessLayer objway = new WaybillDataAccessLayer();
public GetWayBillResponse Get(string id_wb)
{
GetWayBillResponse response = new GetWayBillResponse();
response.Status = "Success";
response.WayBill = objway.GetWaybill(id_wb);
return response;
}
Note that you can simplify your data access even further. You're manually assigning the result columns to the WayBill object. That's repetitive and boring. If you use an Object Relational Mapper such as Dapper, you can remove a lot of that boiler plate code.
Here's what it'd look like using Dapper:
public Waybill GetWaybill(String id_wb)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
return con.QuerySingle<WayBill>("spGetWaybill", new { waybill = id_web }, commandType: CommandType.StoredProcedure);
}
}
Here is my code.
public Dataset ReturnDataset()
{
SqlConnection con = new SqlConnection(Proper connectionstring);
SqlCommand cmd = new SqlCommand(spname,con);
Dataset ds = new Dataset();
try
{
con.Open();
cmd.CommandType = CommandType.StoreProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds,table);
return ds;
}
catch (TimeoutException Ex)
{
con.Close();
if (Ex.Message.Contains("Timeout expired"))
{
ds = null;
return ds;
}
else
{
throw;
}
}
catch (Exception)
{
throw;
}
Does I need to write finally clause to close connection if error occur or not?In first try block I closed connection and then throw exception.Does I need to do same in second block?What will happen If already closed connection and trying to close once again?
It is always good idea to close your connection on finally part of try catch as below, or use using statment and let .net to take care of it :
try{
}
catch{
}
finally{
conn.close();
}
or use using :
using (SqlConnection connection = new SqlConnection(connectionString))
{
}
You can close on error too. If you are worried about the state of connection before closing you can check if it is open and close it in finally:
if (conn != null && conn.State == ConnectionState.Open)
{
conn.close();
}
If not strictly necessary I avoid to create a structured catch cascade.
If necessary, I always try to define a catch cascade from the more specific exception to the more generic exception.
I always put any cleanup logic in the finally block:
SqlConnection con = new SqlConnection(Proper connectionstring);
SqlCommand cmd = new SqlCommand(spname,con);
Dataset ds = new Dataset();
try
{
con.Open();
cmd.CommandType = CommandType.StoreProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds,table);
return ds;
}
catch(TimeoutException toEx)
{
//manage or log specific exception
}
catch(Exception ex)
{
//manage or log generic exception
}
finally
{
//cleanup
con.Close();
ds = null;
}
I would rewrite your code to be something like this:
public DataSet ReturnDataset()
{
// initialize return value
DataSet result = null;
// put SqlConnection and SqlCommand into using () { ....} blocks to ensure proper disposal
using (SqlConnection con = new SqlConnection(Proper connectionstring))
using (SqlCommand cmd = new SqlCommand(spname, con))
{
result = new DataSet();
try
{
con.Open();
// you had a typo: it's a StoredProcedure - not a StoreProcedure
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(result, table);
con.Close();
}
catch (TimeoutException Ex)
{
if (Ex.Message.Contains("Timeout expired"))
{
result = null;
}
else
{
throw;
}
}
}
// return the result - null if an error happened, a valid DataSet otherwise
return result;
}
Points I improved:
declare the possible return value at the beginning, return only once at the very end
removed unnecessary "catch" on an exception you don't do anything with -> just let it happen
put SqlConnection and SqlCommand into using(...) { ... } blocks to ensure proper and speedy disposal
Why don't you use the Using Statement that ensures a proper closing and disposing of the disposable objects? I think you don't need to catch the exceptions at this level, just let them bubble up and, if needed take care of them at the upper level
Here you can simply
public Dataset ReturnDataset()
{
Dataset ds = new Dataset();
using(SqlConnection con = new SqlConnection(Proper connectionstring))
using(SqlCommand cmd = new SqlCommand(spname,con))
{
con.Open();
cmd.CommandType = CommandType.StoreProcedure;
using(SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(ds,table);
}
}
return ds;
}
If this code raises an exception the dataset will be never returned and being a local variable will be quickly become eligible for garbage collection
A better option is to use the using keyword, that does the closing / disposing for you
public Dataset ReturnDataset()
{
using (SqlConnection con = new SqlConnection(connectionstring))
using (SqlCommand cmd = new SqlCommand(spname,con))
{
Dataset ds = new Dataset();
try
{
con.Open();
cmd.CommandType = CommandType.StoreProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds,table);
}
catch (TimeoutException Ex)
{
ds = null;
}
return ds;
}
}
I am working on Microsoft Visual Studio DAL in which I am doing the traditional method of fetching/updating the data to show the reviews of the listed items of website by retrieving data from the ItemDetails table of the website database, for creating the ItemDetails.aspx file. I added a DropDownList Control to displaying all items within its categories.
On selection of category from Drop-down list, it shows all items within that category, with a hyperlink attached "Show Details" to it to show details in a grid-view.
i am newbie i have no idea to create DAL for asp.net website. Need easy guidelines to create DAL for asp.net website. Help will be appreciated. What are the other ways to create DAL rather than SQLadapter.
So for example here is a DAL I've used before for calling SPs.
It allows you to execute stored procedures and return dataset, datatables, success responses etc.
Really it depends on how you intend to access the data, will you be writing Stored Procedures or will you have queries in your code. You also have the option of using Entity Framework/LINQ.
using System;
using System.Collections.Generic;
using System.Web;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Configuration;
public class _DataInteraction
{
#region "Stored Procedures"
public static DataTable stdReturnDataTableQuery(string procedureName, string db)
{
DataTable myDataTable;
SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings[db].ConnectionString);
SqlCommand cmd = new SqlCommand();
SqlDataAdapter myDataAdapter = new SqlDataAdapter();
cmd.CommandText = procedureName;
cmd.CommandType = CommandType.Text;
cmd.Connection = myConnection;
//-----------------------------------------------------------------------
// make our datatable to return
//-----------------------------------------------------------------------
myDataTable = new DataTable();
//-----------------------------------------------------------------------
// fill the datatable with the stored procedure results
//-----------------------------------------------------------------------
try
{
myConnection.Open();
myDataAdapter.SelectCommand = cmd;
myDataAdapter.Fill(myDataTable);
}
catch (Exception ex)
{
//flag as error happened
throw ex;
}
finally
{
myConnection.Close();
if ((myDataAdapter != null))
myDataAdapter.Dispose();
if ((cmd != null))
cmd.Dispose();
}
return myDataTable;
}
// Return a datatable from the database
public static DataTable stdReturnDataTable(string procedureName, List<SqlParameter> myParameters, string db)
{
SqlConnection myConnection = default(SqlConnection);
SqlCommand myCommand = default(SqlCommand);
SqlDataAdapter myDataAdapter = default(SqlDataAdapter);
DataTable myDataTable = default(DataTable);
string connString = null;
// -----------------------------------------------------------------------
// create instance of connection
// -----------------------------------------------------------------------
connString = ConfigurationManager.ConnectionStrings[db].ConnectionString;
myConnection = new SqlConnection();
myConnection.ConnectionString = connString;
//-----------------------------------------------------------------------
// create instance of command and dataadapter
//-----------------------------------------------------------------------
myCommand = new SqlCommand(procedureName, myConnection);
myDataAdapter = new SqlDataAdapter(myCommand);
//-----------------------------------------------------------------------
// say its a stored procedure command
//-----------------------------------------------------------------------
myCommand.CommandType = CommandType.StoredProcedure;
//-----------------------------------------------------------------------
// add any parameters?
//-----------------------------------------------------------------------
if ((myParameters != null))
{
foreach (SqlParameter myParm in myParameters)
{
// add the parameter to the command
myCommand.Parameters.Add(myParm);
}
}
//-----------------------------------------------------------------------
// make our datatable to return
//-----------------------------------------------------------------------
myDataTable = new DataTable();
//-----------------------------------------------------------------------
// fill the datatable with the stored procedure results
//-----------------------------------------------------------------------
try
{
myConnection.Open();
myDataAdapter.Fill(myDataTable);
}
catch (Exception ex)
{
//flag as error happened
throw ex;
}
finally
{
myConnection.Close();
if ((myDataAdapter != null))
myDataAdapter.Dispose();
if ((myCommand != null))
myCommand.Dispose();
}
return myDataTable;
}
// Return a dataset from the database
public static DataSet stdReturnDataset(string procedureName, List<SqlParameter> myParameters, string db)
{
SqlConnection myConnection = default(SqlConnection);
SqlCommand myCommand = default(SqlCommand);
SqlDataAdapter myDataAdapter = default(SqlDataAdapter);
DataSet ds = new DataSet();
string connString = null;
//-----------------------------------------------------------------------
// create instance of connection
//-----------------------------------------------------------------------
connString = ConfigurationManager.ConnectionStrings[db].ConnectionString;
myConnection = new SqlConnection();
myConnection.ConnectionString = connString;
//-----------------------------------------------------------------------
// create instance of command and dataadapter
//-----------------------------------------------------------------------
myCommand = new SqlCommand(procedureName, myConnection);
myDataAdapter = new SqlDataAdapter(myCommand);
//-----------------------------------------------------------------------
// say its a stored procedure command
//-----------------------------------------------------------------------
myCommand.CommandType = CommandType.StoredProcedure;
//-----------------------------------------------------------------------
// add any parameters?
//-----------------------------------------------------------------------
if ((myParameters != null))
{
foreach (SqlParameter myParm in myParameters)
{
// add the parameter to the command
myCommand.Parameters.Add(myParm);
}
}
//-----------------------------------------------------------------------
// fill the datatable with the stored procedure results
//-----------------------------------------------------------------------
try
{
myConnection.Open();
myDataAdapter.Fill(ds);
}
catch (Exception ex)
{
//flag as error happened
throw ex;
}
finally
{
myConnection.Close();
if ((myDataAdapter != null))
myDataAdapter.Dispose();
if ((myCommand != null))
myCommand.Dispose();
}
return ds;
}
// Return success from a query from the database
public static bool db_NonQuerySuccessResponse(string strCommandText, List<SqlParameter> myParameters, string db)
{
SqlConnection SQLConnection = new SqlConnection(ConfigurationManager.ConnectionStrings[db].ConnectionString);
SqlCommand SQLCommand = new SqlCommand();
DataSet ds = new DataSet();
string Value = "";
bool success = false;
try
{
SQLCommand.CommandText = strCommandText;
SQLCommand.CommandType = CommandType.StoredProcedure;
SQLCommand.Parameters.Clear();
if ((myParameters != null))
{
foreach (SqlParameter myParm in myParameters)
{
// add the parameter to the command
SQLCommand.Parameters.Add(myParm);
}
}
SQLCommand.Connection = SQLConnection;
SQLConnection.Open();
SQLCommand.ExecuteNonQuery();
SQLConnection.Close();
success = true;
}
catch (Exception ex)
{
success = false;
return success;
}
return success;
}
// General non query, no results no success
public static bool db_NonQuery(string strCommandText, List<SqlParameter> myParameters, string db)
{
SqlConnection SQLConnection = new SqlConnection(ConfigurationManager.ConnectionStrings[db].ConnectionString);
SqlCommand SQLCommand = new SqlCommand();
DataSet ds = new DataSet();
try
{
SQLCommand.CommandText = strCommandText;
SQLCommand.CommandType = CommandType.StoredProcedure;
SQLCommand.Parameters.Clear();
if ((myParameters != null))
{
foreach (SqlParameter myParm in myParameters)
{
// add the parameter to the command
SQLCommand.Parameters.Add(myParm);
}
}
SQLCommand.Connection = SQLConnection;
SQLConnection.Open();
SQLCommand.ExecuteNonQuery();
SQLConnection.Close();
}
catch (Exception ex)
{
return false;
}
return true;
}
//// Execute scalar on db
//public static string db_Scalar(string strCommandText, ref List<SqlParameter> myParameters, string db)
//{
// SqlConnection SQLConnection = new SqlConnection(ConfigurationManager.ConnectionStrings[db].ConnectionString);
// SqlCommand SQLCommand = new SqlCommand();
// string Value = "";
// SQLCommand.CommandText = strCommandText;
// SQLCommand.CommandType = CommandType.StoredProcedure;
// SQLCommand.Parameters.Clear();
// if ((myParameters != null))
// {
// foreach (SqlParameter myParm in myParameters)
// {
// // add the parameter to the command
// SQLCommand.Parameters.Add(myParm);
// }
// }
// SQLCommand.Connection = SQLConnection;
// SQLConnection.Open();
// Value = SQLCommand.ExecuteScalar;
// SQLConnection.Close();
// return Value;
//}
#endregion
}
Below is 1 sample for reference............
public List<T> GetRequests(string strNo)
{
List<T> objlstMapping = null;
Mapping objMapping = null;
try
{
Database objDbInstance = CreateSQLDatabase(DbConnection.MF);
using (DbCommand objDbCommand = objDbInstance.GetStoredProcCommand(Constants.SP_QUESTS))
{
DALBase.AddDbParam(objDbInstance, objDbCommand, "#No", DbType.AnsiString, ParameterDirection.Input, strFolioNo);
objDbCommand.Connection = objDbInstance.CreateConnection();
objDbCommand.Connection.Open();
using (DbDataReader dr = objDbCommand.ExecuteReader(CommandBehavior.CloseConnection))
{
objMapping = new List<T>();
if (dr.HasRows)
{
while (dr.Read())
{
objMapping = new BrokerFolioMapping();
objMapping .Brok_Code = SProposedValue(dr, "Code");
objMapping .Active = SProposedValue(dr, "Status");
objMapping .AccStmt_Active = SProposedValue(dr, "PortfolioStatus");
objlstFolioMapping.Add(objMapping );
}
}
}
}
}
catch (Exception ex)
{
}
return objlstFolioMapping;
}
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!