Session variable accessibility - asp.net

I have a class which creates a session the following way:
Session["UserId"] = UserId; // UserId = 1
In one of the pages on Page_Load, I retrieve the session variable value this way which works fine:
if (Session["UserId"] != null){
var userid = Session["UserId"];
Welcome.Text = "Hello, " + userid;
}
Now I need to use the value of the session variable in my classes as well. I used the following method to get the session value int useridsession = Convert.ToInt32(HttpContext.Current.Session["UserId"]); but it always returns null whereas the session is correctly read using Session["UserId"]; in my code behind file.
The mentioned class:
public static DataTable ManageBookingsDataTable()
{
int useridsession = Convert.ToInt32(HttpContext.Current.Session["UserId"]);
SqlConnection con = new SqlConnection(Database.ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("select bookings.id,user_id, start_date, end_date, pets.name AS 'Pet name' from bookings AS bookings left join users AS usr ON bookings.user_id=usr.id AND bookings.user_id=1 left join pets AS pets ON pets.id=bookings.pet_id WHERE bookings.user_id=#userid_session", con);
cmd.Parameters.AddWithValue("#userid_session", useridsession);
SqlDataAdapter sqlDa = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
string id = string.Empty;
string name = string.Empty;
string startdate = string.Empty;
string enddate = string.Empty;
string full_string = string.Empty;
sqlDa.Fill(dt);
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
id = dt.Rows[i]["id"].ToString();
var sdate = dt.Rows[i]["start_date"];
name = dt.Rows[i]["Pet name"].ToString();
startdate = dt.Rows[i]["start_date"].ToString();
enddate = dt.Rows[i]["end_date"].ToString();
full_string = startdate + " to " + enddate + " (" + name + ")";
//CurrentBookings.Items.Add(new ListItem(full_string, id));
}
}
return dt;
}
I diagnosed the problem by adding HttpContext.Current.Session["UserId"] = 1; which proves that when I set the session in the same class, the method works.
My question is how do I access the previously created session from any class?

Session should be available for the session regardless of the class. Why don't you set and get
your session values using the same class? All your session stuff in a one place so it is more neat and tidy as well.
Local.MySession.UserId = UserId; //Set here
int myUserId = Local.MySession.UserId; //Get here
//Something like this??
namespace Local
{
//You can add all session variables to this class
public class MySession
{
public static int UserId
{
get
{
return Convert.ToInt32(HttpContext.Current.Session["userId"] ?? "0");
}
set { HttpContext.Current.Session["userId"] = value.ToString(); }
}
public static string UserEmail //For Example another session variable
{
get { return HttpContext.Current.Session["email"] ?? ""; }
set { HttpContext.Current.Session["email"] = value; }
}
}
}

Related

session gets cleared once method finish

I have two methods in my webservice.cs page like below.
[WebMethod(EnableSession = true)]
public void checkEmployee(string emailId, string password)
{
List<Employee> ListEmp = new List<Employee>();
string cs = ConfigurationManager.ConnectionStrings["rushDB"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand("select * from Employees where Email='" + emailId + "' AND Password='" + password + "'", con);
string personName = null;
string personEmail = null;
string personDeptName = null;
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
if (rdr.HasRows == true)
{
while (rdr.Read())
{
Employee empChild = new Employee();
empChild.ID = Convert.ToInt16(rdr["ID"]);
empChild.Name = rdr["Name"].ToString();
empChild.Email = rdr["Email"].ToString();
empChild.Password = rdr["Password"].ToString();
empChild.DepartName = rdr["DepartName"].ToString();
personName = rdr["Name"].ToString();
personEmail = rdr["Email"].ToString();
personDeptName = rdr["DepartName"].ToString();
ListEmp.Add(empChild);
}
HttpContext.Current.Session["NamePerson"] = personName;
HttpContext.Current.Session["EmailPerson"] = personEmail;
HttpContext.Current.Session["DepartPerson"] = personDeptName;
JavaScriptSerializer js = new JavaScriptSerializer();
Context.Response.Write(js.Serialize(ListEmp));
}
}
}
[WebMethod(EnableSession = true)]
public void GetCurrentData()
{
Employee ListEmp = new Employee();
if (HttpContext.Current.Session["NamePerson"] != null)
ListEmp.Name = HttpContext.Current.Session["NamePerson"].ToString();
if (HttpContext.Current.Session["EmailPerson"] != null)
ListEmp.Email = HttpContext.Current.Session["EmailPerson"].ToString();
if (HttpContext.Current.Session["DepartPerson"] != null)
ListEmp.DepartName = HttpContext.Current.Session["DepartPerson"].ToString();
JavaScriptSerializer js = new JavaScriptSerializer();
Context.Response.Write(js.Serialize(ListEmp));
}
My issue is that the session created in checkEmployee gets vanished after that method checkEmployee finishes its execution.
I want to retrieve the session values in GetCurrentData but i am unable to do so. Any solution would help me. i have googled it but that didn't helped.
You need a cookie-jar to be able to retain session-state on Web Services. Depending on how you're consuming the service it can get quite complicated if you haven't done it before...
Have at look at the following articles:
http://www.codeproject.com/Articles/322436/RestSessionState
http://www.codeproject.com/Articles/188749/WCF-Sessions-Brief-Introduction

Losing first record and the values keep changing when loading reader to datatable

I load reader to my table like this
connection.Open();
sqlCmd = new SqlCommand(sqlCmd.CommandText, connection);
SqlDataReader sqlReader = sqlCmd.ExecuteReader();
DataTable dt = new DataTable();
sqlReader.Read();
dt.Load(sqlReader);
But it looks like I cannot retrieve the first record of fetch data.
The second problem is when I call the reader several times after that:
string comName = dt.Rows[0]["companyName"].ToString();
//To get address
sqlCmd.CommandText = addr;
sqlCmd.Parameters.AddWithValue("companyName", comName);
using (var addressReader = sqlCmd.ExecuteReader())
{
if (addressReader.Read())
{
Label1.Text = Label1.Text + " " + addressReader["address"].ToString();
}
}
//To get keyProcesses
sqlCmd.Parameters.Clear();
sqlCmd.CommandText = keyProcesses;
sqlCmd.Parameters.AddWithValue("companyName", comName);
using (var keyProcessesReader = sqlCmd.ExecuteReader())
{
if (keyProcessesReader.Read())
{
Label1.Text = Label1.Text + " " + keyProcessesReader.GetString(0);
}
}
But I find out that these reading also may changes the value of my datatable dt above! How could I only load data to dt at the first reading and keep it there without changing any more ?
Ps: In attempt to overcome the second problem, I am trying to store dt values in list
public class CompanyModel
{
public string compnName { get; set; }
public string compnAddress { get; set; }
public string compnKeyProcesses { get; set; }
public string compnStandards { get; set; }
}
then
List<CompanyModel> companies = new List<CompanyModel>();
for(int i = 0; i < dt.Rows.Count; i++)
{
companies.Add(new CompanyModel
{
compnName = dt.Rows[i]["companyName"].ToString(),
compnAddress = dt.Rows[i]["address"].ToString()
});
}
companyRepeater.DataSource = companies;
companyRepeater.DataBind();
Now, how do I access each company name in the list to make query on that name value accordingly, then input the new result to the list?
I tried:
foreach(List<Component> compnName in companies.Contains("companyName")
{
sqlCmd.CommandText = getKey;
sqlCmd.Parameters.AddWithValue("companyName", compnName);
using (var keyReader = sqlCmd.ExecuteReader())
{
if (keyReader.Read())
{
companies.Add(new CompanyModel compnKeyProcesses = keyReader.GetString("key"));
}
}
sqlCmd.CommandText = getstandard;
sqlCmd.Parameters.AddWithValue("companyName", compnName);
using (var standardReader = sqlCmd.ExecuteReader())
{
if (standardReader.Read())
{
companies.Add(new CompanyModel compnStandards = keyReader.GetString("standards"));
}
}
Try this for your first problem
SqlDataAdapter sdr = new SqlDataAdapter(sqlCmd.CommandText, connection);
DataTable dt=new DataTable();
sdr.Fill(dt);
you can display this whole data as a matter of confirmation by taking a datagridview
dataGridView1.DataSource=dt;

How do I convert an object containing an Oracle Date to a DateTime?

The method below uses OracleDataReader.GetValues() to stuff SQL results into an array of objects.
From that array, calling methods can convert, e.g. numbers to longs with Convert.ToInt64(row["FOO_COLUMN"]), but cannot reliably get a date. I cannot use TO_CHAR(some_date_format) because the method must work with SELECT * FROM ....
I've tried checking each column to see if it is an OracleDate via the three lines of commented code below. The contents of the if() statement in question may be incorrect, but it doesn't matter because the if() condition is never met.
I've searched but was surprised that either my search skills need some work or that no one has ever asked this question, probably the former.
public IDictionary<int, IDictionary<string, object>>
dbQuery(string sql, Dictionary<string, object> parameters = null, string connectionString = null) {
var dbResults = new Dictionary<int, IDictionary<string, Object>>();
if(connectionString == null) connectionString = this.defaultQueryConnectionString;
using(var con = new OracleConnection(connectionString)) {
using(var cmd = new OracleCommand(sql, con)) {
cmd.BindByName = true;
if(parameters != null) {
OracleParameter[] parameterArray = new OracleParameter[parameters.Count];
int parameterIndex = 0;
foreach(var parameter in parameters) {
parameterArray[parameterIndex] = new OracleParameter(parameter.Key, parameter.Value);
++parameterIndex;
}
cmd.Parameters.AddRange(parameterArray);
}
con.Open();
var reader = cmd.ExecuteReader();
int columnCount = reader.FieldCount;
object[] columns = new object[columnCount];
int rowNum = 0;
while(reader.Read()) {
reader.GetValues(columns);
var colval = new Dictionary<string, object>();
for(int columnIndex = 0; columnIndex < columnCount; ++columnIndex) {
//if(columns[columnIndex] is OracleDate) {
// columns[columnIndex] = Convert.ToDateTime(columns[columnIndex]);
//}
string colName = reader.GetName(columnIndex).ToUpperInvariant();
colval.Add(colName.ToUpperInvariant(), columns[columnIndex]);
}
dbResults.Add(rowNum, colval);
++rowNum;
}
}
}
return dbResults;
}
DateTime.Parse(reader[column].ToString())
The OracleDateTime object is actually an Array of bytes. Another solution (that does not use string conversion) is:
OracleDateTime oDT = (OracleDateTime) reader[column];
DateTime? myDT = null;
if(!oDT.IsNull)
myDT = new DateTime(oDT.Year, oDT.Month, oDT.Day
, oDT.Hour, oDT.Minute, oDT.Second);

I need to fetch all users email of a particular group using AD in .net 2.0

I know there are lots of methods already given in stackoverflow but in my case all of them taking too long time. I post a method which takes less time but still it is too long to implement. Please help me so that it takes less execution time. Also take consideration that i am using .net 2.0 framework.
try
{
List<string> lstEmails = new List<string>();
string filter1 = string.Format("(anr={0})", "groupname");
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = filter1;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("mail");
IEnumerable res = (IEnumerable)searcher.FindOne().GetDirectoryEntry().Invoke("members");
//IEnumerable<string> rest = (IEnumerable<string>)res;
if (res != null)
{
try
{
int index = 0;
foreach (IEnumerable resl in res)
{
DateTime start = DateTime.Now;
DirectoryEntry dr = new DirectoryEntry(resl);
string strEmail = null;
if (dr.Properties["mail"].Value != null)
{
strEmail = dr.Properties["mail"].Value.ToString();
Console.WriteLine(strEmail);
DateTime stop = DateTime.Now;
Console.WriteLine((stop - start).TotalMinutes.ToString());
index++;
Console.WriteLine(index.ToString());
}
if (!string.IsNullOrEmpty(strEmail))
{
// groupMemebers.Add("sam",strEmail);
}
}
}
catch { }
}
}
catch { }
This is your suggested method Daro..
DirectoryContext context = new DirectoryContext(DirectoryContextType.Domain, domain, "domainname" + strLDAPUserName, strLDAPPassword);
DomainController controller = DomainController.FindOne(context);
DirectoryEntry entry = new DirectoryEntry(string.Format("LDAP://{0}",controller.Domain), strLDAPUserName, strLDAPPassword, AuthenticationTypes.Secure);
List<string> userList = new List<string>();
DateTime StartTime = DateTime.Now;
using (DirectorySearcher ds = new DirectorySearcher(entry))
{
ds.PropertiesToLoad.Add("mail");
ds.PageSize = 10000;
string DistingushiedName = "CN=" + groupName + ",OU=Users,dc=CompanyName,dc=com";
ds.Filter = "(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:="+DistingushiedName+"))";
ds.SearchScope = SearchScope.Subtree;
try
{
foreach (SearchResult user in ds.FindAll())
{
try
{
userList.Add(user.Path);//.Properties["mail"][0].ToString());
}
catch (Exception E)
{
throw new Exception(E.Message);
}
}
}
catch(Exception E)
{
throw new Exception(E.Message);
}
DateTime EndTime = DateTime.Now;
TimeSpan Dif = EndTime.Subtract(StartTime);
}
Here is your solution:-
string[] email = new string[0];
DirectoryEntry entry = new DirectoryEntry("LDAP://OU=Users,dc=me,dc=com", username, password);
string groupName = "GroupName";//Group NAme
DirectorySearcher groupSearch = new DirectorySearcher(entry);
groupSearch.Filter = "(SAMAccountName=" + groupName + ")";
groupSearch.PropertiesToLoad.Add("member");
SearchResult groupResult = groupSearch.FindOne(); // getting the members who belongs to the concern groupname
if (groupResult != null)
{
email = new string[groupResult.Properties["member"].Count]; //creatign an array to store all the email address
for (int iSearchLoop = 0; iSearchLoop < groupResult.Properties["member"].Count; iSearchLoop++)
{
string userName = groupResult.Properties["member"][iSearchLoop].ToString();
int index = userName.IndexOf(',');
userName = userName.Substring(0, index).Replace("CN=", "").ToString(); // the name of the user will be fetched.
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(name=" + userName + ")";
search.PropertiesToLoad.Add("mail");
SearchResult result = search.FindOne(); //finding the mail id
if (result != null)
{
email[iSearchLoop] = result.Properties["mail"][0].ToString(); //assigning the mail id to an array....
}
}
}
Hope this helps you
Easy enough (if your AD is 2003 R2 or higher):
List<string> userList = new List<string>();
DateTime StartTime = DateTime.Now;
using (DirectorySearcher ds = new DirectorySearcher(new DirectoryEntry ("GC://DC=YourDomain,DC=com")))
{
ds.PropertiesToLoad.Add("mail");
ds.PageSize = 10000;
ds.Filter = "(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=YOUR_GROUP'S DN))";
ds.SearchScope = SearchScope.Subtree;
try
{
foreach (SearchResult user in ds.FindAll())
{
try
{
userList.Add(user.Path);//.Properties["mail"][0].ToString());
}
catch (Exception E)
{
throw new Exception(E.Message);
}
}
}
catch(Exception E)
{
throw new Exception(E.Message);
}
DateTime EndTime = DateTime.Now;
TimeSpan Dif = EndTime.Subtract(StartTime);
}
Replace YOUR_GROUP'S DN with the distiguished name of your group...
memberof:1.2.840.113556.1.4.1941:= is the "new" LDAP_MATCHING_RULE_IN_CHAIN operator, and retrieves all group members. Look here to see if your AD is ready and get more information.
Edit:
I gave you an answer, but an explanation might help further.
In general you should avoid ANR searches because they expand to large wildcard OR queries. Use them only if you have no idea which property contains the name you are searching for. They are much slower than explicit AND searches.
Secondly if you have more than one domain, you should turn off referral chasing unless you want to search through all domains until you get a hit. In this case it would be better to do a GC:// than a LDAP:// search to find the object you’re looking for, than do an LDAP search on that object. Depending on what you are looking for the GC query could well be enough
Edit 2:
Modified the code to give more error information and get the user path instead of E-Mail.
Hey this is the correct way...
try
{
List<string> ReturnArray = new List<string>();
DirectoryContext context = new DirectoryContext(DirectoryContextType.Domain, domainName, domainName + "\\" + UserName, Password);
DomainController controller = DomainController.FindOne(context);
string LDAPAddress = string.Format("LDAP://{0}", controller.Domain);
DirectoryEntry deDirEntry = new DirectoryEntry(LDAPAddress, UserName, Password);
deDirEntry.AuthenticationType = AuthenticationTypes.Secure;
DirectorySearcher mySearcher = new DirectorySearcher(deDirEntry);
mySearcher.PropertiesToLoad.Add("distinguishedName");
string sFilter = String.Format("(&(objectcategory=group)(cn=" + GroupName + "))");
mySearcher.Filter = sFilter;
mySearcher.Sort.Direction = SortDirection.Ascending;
mySearcher.Sort.PropertyName = "cn";
SearchResult result;
DirectoryEntry ResultEntry;
result = mySearcher.FindOne();
ResultEntry = result.GetDirectoryEntry();
GroupName = ResultEntry.Properties["distinguishedName"].Value.ToString();
mySearcher = new DirectorySearcher(deDirEntry);
mySearcher.PropertiesToLoad.Add("cn");
mySearcher.PropertiesToLoad.Add("mail");
sFilter = String.Format("(&(objectClass=person)(memberOf={0}))", GroupName);
mySearcher.Filter = sFilter;
mySearcher.Sort.Direction = SortDirection.Ascending;
mySearcher.Sort.PropertyName = "cn";
SearchResultCollection results;
results = mySearcher.FindAll();
foreach (SearchResult resEnt in results)
{
ResultPropertyCollection propcoll = resEnt.Properties;
foreach (string key in propcoll.PropertyNames)
{
if (key == "mail")
{
foreach (object values in propcoll[key])
{
if (!String.IsNullOrEmpty(values.ToString()))
{
ReturnArray.Add(values.ToString());
Console.WriteLine(values.ToString());
}
}
}
}
}
return ReturnArray;
}
catch
{
return null;
}
Thanks everyone for your valuable suggesstion

Asp.net Session Url Asp.net Page.IsPostBack getuserinfo error

Okay,The Other errors are fixed now im at this point where my other pages need their code to be updated:
Error : Object reference not set to an instance of an object.
public partial class Controls_GetUserScraps : System.Web.UI.UserControl
{
DataBaseClass dbClass = new DataBaseClass();
public DataTable dt;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GetUserScraps(int.Parse(Session["UserId"].ToString()));
}
}
public void GetUserScraps(int Id)
{
string getUserScraps = "SELECT u.Id as UserId,u.FirstName,,u.LastName,u.ImageName,s.FromId,s.ToId,s.Message,s.SendDate,s.ID as ScrapId FROM [User] as u, Scrap as s WHERE u.Id=s.FromId AND s.ToId='" + Request.QueryString["Id"].ToString() + "'";
dt = dbClass.ConnectDataBaseReturnDT(getUserScraps);
if (dt.Rows.Count > 0)
{
GridViewUserScraps.DataSource = dt;
GridViewUserScraps.DataBind();
}
}
I replaced Session ID to UserId and it removed the error now it has displayed another error under.
Error : Object reference not set to an instance of an object.
string getUserScraps = "SELECT u.Id as UserId,u.FirstName,,u.LastName,u.ImageName,s.FromId,s.ToId,s.Message,s.SendDate,s.ID as ScrapId FROM [User] as u, Scrap as s WHERE u.Id=s.FromId AND s.ToId='" + Request.QueryString["Id"].ToString() + "'";
Adding your fix created this new error:
I think the easiest way to do this would be to have the private bool UserAuthenticate method take an out parameter which you can use to return the actual user name from the database.
private bool UserAuthenticate(string UserName, string Password, out string actualUserName)
{
actualUserName = string.Empty;
bool boolReturnValue = false;
//--------------------------------
//Check UserID From Config File
if (UserName == "User" && Password == "Pass")
{
boolReturnValue = true;
return boolReturnValue;
}
else
{
//--------------------------------
dt = new DataTable();
string chkUser = "Select * FROM [User] where Email='" + UserName + "' AND Password='" + Password + "'";
dt = dbClass.ConnectDataBaseReturnDT(chkUser);
if (dt.Rows.Count > 0)
{
//TODO: grab the actual user name from the row and assign it to actualUserName. For example:
actualUserName = dt.Rows[0]["FullName"];
boolReturnValue = true;
Session["UserId"] = dt.Rows[0]["Id"].ToString();
string updateLastLogin = "Update [User] SET LastLogin='" + System.DateTime.Now.ToString() + "' where Id='" + Session["UserId"].ToString() + "'";
dbClass.ConnectDataBaseToInsert(updateLastLogin);
}
return boolReturnValue;
}
}
After that you would then need to do something like this in the OnAuthenticate method:
string actualUserName;
Authenticated = UserAuthenticate(ctlLogin.UserName, ctlLogin.Password, out actualUserName);
And the redirect would now be:
Response.Redirect("Home.aspx/" + actualUserName);

Resources