session gets cleared once method finish - asp.net

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

Related

asp.net mvc using string id on details view

Please help me to find error on my code
public ActionResult Details(string id)
{
String connectionString = ConfigurationManager.ConnectionStrings["SAPB1"].ConnectionString;
SqlConnection conn = new SqlConnection(connectionString);
String sql = "Select a.[CardCode] As CCODE,a.[CardName] As Name from ocrd a where a.CardCode = " + id;
SqlCommand cmd = new SqlCommand(sql, conn);
BPModel BP = new BPModel();
using (conn)
{
conn.Open();
if (string.IsNullOrEmpty(id))
{
}
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
BP.CCODE = rdr["CCODE"].ToString();
BP.Name = rdr["Name"].ToString();
}
}
return View(BP);
}
You need to wrap your id values inside single quote ('). Try like below.
String sql = "Select a.[CardCode] As CCODE,a.[CardName] As Name from ocrd a where a.CardCode = '" + id + "'";

Increase data insert performance

We have created a code that loops in to CosmosDb records and inserts values to Sql db. But in the process, the data insertion perfomance is very slow. please help with suggestions, here is the code. This process is taking more than 4 hours for inserting a data of 4000 rows.
namespace PushNotificationUserInsert
{
class Program
{
static void Main(string[] args)
{
Task.Run(async () =>
{
#region Variables
var endpoint = ConfigurationManager.AppSettings["DocDbEndpoint"];
var masterKey = ConfigurationManager.AppSettings["DocDbMasterKey"];
var connetionString = ConfigurationManager.AppSettings["SQL_connetionString"].ToString();
// var useremail = "\"\"";
string path = #"xxxx.txt";
string[] useremails = File.ReadAllLines(path);
List<string> It = useremails.ToList();
var newIt = It.Distinct().ToList();
var channel = "\"msteam\"";
var cnn = new SqlConnection(connetionString);
var cnnInsert = new SqlConnection(connetionString);
string query = null;
cnn.Open();
foreach (var email in newIt)
{
query = "SELECT * FROM c where c.document.bot_js.mail = \"" + email + "\" AND CONTAINS(c.id," + channel + ", true)";
dynamic responses = "";
JSONModel.Rootobject records = null;
string conversationId = "";
//string email = "";
#endregion
#region Reading data from SQL
// cnn.Open();
SqlDataReader dataReader;
String Output = "";
SqlCommand command = new SqlCommand(#"SELECT [ConversatonReferenceJson] FROM [dbo].[ConversationReferences] where emailid like ''", cnn);
//command = new SqlCommand(sql, cnn);
dataReader = command.ExecuteReader();
while (dataReader.Read())
{
Output = dataReader.GetValue(0).ToString();
records = JsonConvert.DeserializeObject<JSONModel.Rootobject>(Output);
}
dataReader.Close();
dataReader.Dispose();
#endregion
string[] readText = File.ReadAllLines(path);
//List<string> It = readText.ToList();
//var newIt = It.Distinct().ToList();
//foreach (string email in newIt)
//{
Console.WriteLine(email);
try
{
#region reading data from Consmos DB
using (var client = new DocumentClient(new Uri(endpoint), masterKey))
{
responses = client.CreateDocumentQuery(UriFactory.CreateDocumentCollectionUri("Cosmosdbname", "cosmosdbtablebame"), query).ToList();
}
#endregion
#region Looping throught each cosmos DB records and insert value in SQL
foreach (var response in responses)
{
conversationId = response.id.Remove(0, 26);
records.conversation.id = conversationId;
cnnInsert.Open();
SqlCommand commInsert = new SqlCommand("INSERT INTO [ConversationReferences] VALUES " +
"(#ChannelId, #UserId, #ConverJson, #ID, #EmailID)", cnnInsert);
commInsert.Parameters.AddWithValue("#ChannelId", "xxxx");
commInsert.Parameters.AddWithValue("#UserId", "tobedeleted");
commInsert.Parameters.AddWithValue("#ConverJson", JsonConvert.SerializeObject(records));
commInsert.Parameters.AddWithValue("#ID", "tobedeleted");
commInsert.Parameters.AddWithValue("#EmailID", email);
commInsert.ExecuteNonQuery();
cnnInsert.Close();
Console.WriteLine("records updated for " + email);
}
#endregion
}
catch (Exception ex)
{
cnnInsert.Close();
throw;
}
finally
{ cnnInsert.Close(); }
Console.ReadKey();
}
}).Wait();
}
}

Session variable accessibility

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; }
}
}
}

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

storing data results from stored procedures

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; }
}

Resources