I have 2 arraylists. One is principleList which contains integer values that denotes roles (Admin, Project Manager etc.). Second is codeList which contains the various codes (e.g. AddUserProfile) for which I want to get permissions. I have a stored procedure "AllowedToPerformFunction" that returns allowed =0 or 1 depending on if a role can perform a code.
I am having trouble with the logic for this since I have multiple ids and multiple codes. For each id, I need to call the stored procedure with each code and store this.
I am trying to store permissions in a hashtable for various roles such as Admin, Project Manager. So for example for Admin i would need to store:
Admin (id =1)
code = "AddUser",allowed =1
code="AddProject",allowed=0
hashtable format (key,value) = (1, AddUser-1), (1, AddProject-0)
Here is my code that isn't working:
protected void Page_Load(object sender, EventArgs e)
{
getPermissions();
}
void getPermissions()
{
using (SqlConnection conn = new SqlConnection("GoalFishConnectionString")){conn.Open();
ArrayList idList = getPrincipleIds();
ArrayList codeList = getCodes();
ArrayList allowList = new ArrayList();
for (int i = 0; i < idList.Count; i++)
{
MessageBox.Show(idList[i].ToString());
for (int j = 0; j < codeList.Count; j++)
{
MessageBox.Show(codeList[j].ToString());
SqlCommand command2 = new SqlCommand("AllowedToPerformFunction", conn);
command2.CommandType = CommandType.StoredProcedure;
command2.Parameters.Clear();
command2.Parameters.Add("#principalID", SqlDbType.Int).Value = idList[i];
command2.Parameters.Add("#contextID", SqlDbType.Int).Value = idList[i];
command2.Parameters.Add("#roleCode", SqlDbType.VarChar).Value = codeList[j];
command2.Parameters.Add("#allowed", SqlDbType.Int);
command2.Parameters["#allowed"].Direction = ParameterDirection.Output;
command2.ExecuteNonQuery();
int allowed = (int)command2.Parameters["#allowed"].Value;
allowList.Add(command2.Parameters["#allowed"].Value);
}
}}}
ArrayList getPrincipleIds()
{
ArrayList principleList = new ArrayList();
using (SqlConnection conn = new SqlConnection("GoalFishConnectionString")){
conn.Open();
SqlCommand cmd = new SqlCommand("GetPrinciples", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
principleList.Add(rdr["unit_id"]);
}
rdr.Close();
}
return principleList;
}
ArrayList getCodes()
{
ArrayList codesList = new ArrayList();
using (SqlConnection conn = new SqlConnection("GoalFishConnectionString")){
conn.Open();
SqlCommand command = new SqlCommand("GetCodes", conn);
command.CommandType = CommandType.StoredProcedure;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
codesList.Add(reader["Code"]);
//MessageBox.Show(reader["Code"].ToString());
}
reader.Close();
}
}
return codesList;
}
Any advice or help with this would greatly be appreciated.
Why not make a class like this and store it in the session? This way you only have to worry about permissions for one user (unless a user can be admin & Project Manager at the same time)
public class LoginUser
{
public loginUser
{
this.Permission = LoadAllPermissions()
}
public string Role { get; set; }
public Dictionary<integer, string> Permission { get; set; }
}
Related
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);
}
}
I'm checking if a barcode from a database table(using a select query) exists and insert the details into another database table else the barcode does not exist. The inserts fine but I would like to count the number of barcodes entered. Say within a session an user enters 5 barcodes then the total count is 5 but my code keeps returning 1 and not incrementing.
protected void btnReturn_Click(object sender, EventArgs e)
{
string barcode = txtBarcode.Text;
string location = lblLocation.Text;
string user = lblUsername.Text;
string actType = lblAct.Text;
string date = lblDate.Text;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["TWCL_OPERATIONSConnectionString"].ToString());
//commands identifying the stored procedure
SqlCommand cmd = new SqlCommand("selectCrate", conn);
SqlCommand cmd1 = new SqlCommand("CreateCrateBox", con);
// execute the stored procedures
cmd.CommandType = CommandType.StoredProcedure;
cmd1.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#crateno", barcode);
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows) {
while (reader.Read())
{
lblResult.Text = reader[0].ToString();
lblResult1.Text = reader[1].ToString();
cmd1.Parameters.Add("#crateno", SqlDbType.NVarChar).Value = barcode);
cmd1.Parameters.Add("#CurrentLocation", SqlDbType.NVarChar).Value = location;
cmd1.Parameters.Add("#Username", SqlDbType.NVarChar).Value = user;
cmd1.Parameters.Add("#Date", SqlDbType.DateTime).Value = date;
cmd1.Parameters.Add("#status", SqlDbType.NVarChar).Value = actType;
counter = counter + 1;
}
reader.Close();
cmd1.ExecuteNonQuery();
txtCount.Text = counter.ToString();
lblCount.Text = string.Format("Number of rows: {0}", counter);
}
else
{
lblError.Text = barcode + " does not exist!!";
}
}
You can store the number in session then do something with it when the session ends (store it in a database or whatever you want). Declare a session variable:
Session[“NumInserts”] = 0;
Then update it with each insert:
Session[“NumInserts”] = (int) Session[“NumInserts”] + 1;
That variable will be maintained as long as the session exists. Also, make sure you only declare the session variable once and don’t ever allow it to reset during the session’s life cycle. Otherwise, it will go back to 0 and give you inaccurate results.
i rechecked to make sure and i misunderstood your question which led to some confusion.
And to answer your question i don't think there is any easy solution to update realtime the numbers. Any solution of i can think of is websocket connection which I personally have no knowledge of inside webforms(Don't even know if its possible).
I formatted your code. This should give you the total rows back in one go(no realtime update on screen).
protected void btnReturn_Click(object sender, EventArgs e)
{
int counter = 0;
string barcode = txtBarcode.Text;
string location = lblLocation.Text;
string user = lblUsername.Text;
string actType = lblAct.Text;
string date = lblDate.Text;
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["TWCL_OPERATIONSConnectionString"].ToString()))
{
con.Open();
//commands identifying the stored procedure
using (SqlCommand cmd = new SqlCommand("selectCrate", con))
{
using (SqlCommand cmd1 = new SqlCommand("CreateCrateBox", con))
{
// execute the stored procedures
cmd.CommandType = CommandType.StoredProcedure;
cmd1.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#crateno", barcode));
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
lblResult.Text = reader[0].ToString();
lblResult1.Text = reader[1].ToString();
cmd1.Parameters.Add("#crateno", SqlDbType.NVarChar).Value = barcode;
cmd1.Parameters.Add("#CurrentLocation", SqlDbType.NVarChar).Value = location;
cmd1.Parameters.Add("#Username", SqlDbType.NVarChar).Value = user;
cmd1.Parameters.Add("#Date", SqlDbType.DateTime).Value = date;
cmd1.Parameters.Add("#status", SqlDbType.NVarChar).Value = actType;
counter++;
}
cmd1.ExecuteNonQuery();
txtCount.Text = counter.ToString();
lblCount.Text = string.Format("Number of rows: {0}", counter);
}
else
{
lblError.Text = barcode + " does not exist!!";
}
}
}
}
}
}
Trying to remove duplicate treenodes when adding data from sql server.
Data is added to tree ok but I can't seem to work out how to remove duplicates of the parent nodes.
public partial class SYS_Main : System.Web.UI.Page
{
public TreeNode testerr = new TreeNode();
private List<string> _isdupe = new List<string>();
private List<string> _dupe = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
PopulateRootLevel();
TV_Test.CollapseAll();
}
private void PopulateRootLevel()
{
const string connectionString = ("user=;" +
"password=;server =UsersSQL;" +
"Trusted_Connection=yes;" +
"database=System Details; " +
"connection timeout=30");
// connects to sql DB
// sql connection
SqlConnection objConn = new SqlConnection(connectionString);
// sql queries to server
SqlCommand objCommand = new SqlCommand("SELECT Contract, [Server Name],[IP Address] FROM tblServers where Contract !='' AND [SERVER NAME] !='';", objConn);
SqlCommand testquery = new SqlCommand("select s.contract ,COUNT(*)from [System Details].dbo.tblServers s where contract !='' group by Contract having count (*)>1 ;", objConn);
// data adapater holds values of sql queries
SqlDataAdapter da = new SqlDataAdapter(objCommand);
// datatable to hold query data into nodes
DataTable dt = new DataTable();
// data table populated
da.Fill(dt);
//Calls popnodes method and includes dt + nodes for
PopulateNodes2(dt,TV_Test.Nodes);
}
//pop nodes method
private void PopulateNodes2(DataTable dt, TreeNodeCollection nodes)
{
foreach (DataRow dr in dt.Rows)
{
TV_Test.Nodes.Clear();
TreeNode IP = new TreeNode();
IP.Text = dr["IP Address"].ToString();
// new instance of a treenode
testerr = new TreeNode();
testerr.Text = dr["Server Name"].ToString();
testerr.ChildNodes.Add(IP);
TreeNode parent = new TreeNode("Text1");
parent.Text = "keyText1";
parent.Text = (dr["Contract"]).ToString();
_isdupe.Add(parent.Text);
parent.ChildNodes.Add(testerr);
nodes.Add(parent);
string trued;
trued = _isdupe.Distinct().ToString();
if (trued.Equals(parent.Text))
{
TV_Test.Nodes.Remove(parent);
}
else
{
}
}
}
}
}
I think your algorithm is wrong, if you order your query you'll be able to fill the treeview with no duplicate directly.
While fetching a record in asp.net from sql server it always return null..here's code-
Even if record is available in database, object oid will have null at run time.
Please help.
thanks.
protected void btnLogin_Click(object sender, EventArgs e)
{
string cs = ConfigurationManager.ConnectionStrings["DBMS"].ConnectionString;
SqlConnection con = new SqlConnection(cs);
SqlCommand com = new SqlCommand("select id from reg where user=#user and password=#pass", con);
com.Parameters.AddWithValue("#user", txUName.Text);
com.Parameters.AddWithValue("#pass", txPass.Text);
con.Open();
var oid = com.ExecuteScalar();
con.Close();
if (oid == null)
{
lblEr.Visible = true;
}
else
{
Session.Add("id", oid.ToString());
Session.Add("user", txUName.Text);
com = new SqlCommand("select type from dbo.reg where user=#u", con);
com.Parameters.AddWithValue("#u", txUName.Text);
con.Open();
var otype = com.ExecuteScalar();
con.Close();
var vtype = "admin";
if (vtype == otype.ToString())
{
Session.Add("admin", otype.ToString());
Response.Redirect("admin.aspx");
}
Response.Redirect("user.aspx");
}
}
It worked just by correcting following syntax-
SqlCommand com = new SqlCommand("select id from reg where [user]=#user and [password]=#pass", con);
Since 'user' is also name of a user in sql server, so when we want to use it at another place like here as column then we have to use it as [user].
I did sql command with SqlDataReader but I had this error
System.IndexOutOfRangeException: UserName
Page Load event:
protected void Page_Load(object sender, EventArgs e)
{
using (SqlConnection con = Connection.GetConnection())
{
SqlCommand Com = new SqlCommand("Total", con);
Com.CommandType = CommandType.StoredProcedure;
SqlDataReader Dr = Com.ExecuteReader();
if (Dr.Read())
{
string Result= Dr["UserName"].ToString();
Lbltotal.Text = Result;
}
}
}
Stored Procedure:
Alter proc Total
as
begin
select Count (UserName) from Registration
end
Change your storder procedure to:
Alter proc Total
as
begin
select Count (UserName) as UserName from Registration
end
You're not returning any column called UserName - you're just returning a count which has no explicit column name.
If you have something like this - just a single value - you could also use the ExecuteScalar method which will return exactly one value:
using(SqlCommand Com = new SqlCommand("Total", con))
{
Com.CommandType = CommandType.StoredProcedure;
int count = (int)Com.ExecuteScalar();
}
If you insist on using the SqlDataReader, you just need to use a positional parameter:
using(SqlCommand Com = new SqlCommand("Total", con))
{
Com.CommandType = CommandType.StoredProcedure;
using(SqlDataReader Dr = Com.ExecuteReader())
{
if (Dr.Read())
{
string Result= Dr[0].ToString(); // take value no. 0 - the first one
Lbltotal.Text = Result;
}
}
}