Issue With Get Set Properties c# - c#

im stuck with this and im really going to bang my head against a wall in a minutes
I have a logging page where the user enters there username and password and clicks login when they have pressed this a function is called to get all the user details i.e firstname surname Email AccountType Examtaken etc within the function im trying to set "Get; Set;" Properties so i can use them on the home page, but for some stupid reason un-known to me its not working! below you will see the method that is called when the user clicks login
public class ExamMethods
{
public int UserID { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public int AccountType { get; set; }
public bool ExamTaken { get; set; }
private enum Datafield
{
UserID,
FirstName,
Surname,
Email,
AccountType,
ExamTaken,
}
public Hashtable CheckLogin(Hashtable Usercredentials)
{
try
{
SqlConnection Connection = new SQLAccess().CreateConnection();
SqlCommand Command = new SqlCommand("GetUserDetails", Connection);
Command.CommandType = System.Data.CommandType.StoredProcedure;
foreach (DictionaryEntry SpParameter in Usercredentials)
{
Command.Parameters.Add(new SqlParameter(SpParameter.Key.ToString(), SpParameter.Value.ToString()));
}
SqlDataReader da = Command.ExecuteReader();
while (da.Read())
{
Details.Add("UserID", da["UserID"]);
UserID = (da.IsDBNull((int)Datafield.UserID)) ? 0 : da.GetInt32((int)Datafield.UserID);
Details.Add("FirstName", da["FirstName"]);
FirstName = (da.IsDBNull((int)Datafield.FirstName)) ? "" : da.GetString((int)Datafield.FirstName);
Details.Add("Surname", da["Surname"]);
Surname = (da.IsDBNull((int)Datafield.Surname)) ? "" : da.GetString((int)Datafield.Surname);
//Details.Add("AccountType", da["AccountType"]);
//AccountType = (da.IsDBNull((int)Datafield.AccountType)) ? 0 : da.GetInt32((int)Datafield.AccountType);
//Details.Add("ExamTaken", da["ExamTaken"]);
//ExamTaken = (da.IsDBNull((int)Datafield.ExamTaken)) ? false : da.GetBoolean((int)Datafield.ExamTaken);
}
Connection.Close();
da.Close();
return Details;
}
catch
{
Console.WriteLine("Error Checking Login Details");
return Details;
}
}
}
as you can see from the above in the while(da.read) im assigning the values to a hashtable and the get set methods when debuggin i can see values going in! and im 100% this values arent null or empty
the code then reverts back to the login page with it results if all is fine then response.redirect to the home page where the user can take the exam, but in the page load of the home.aspx i have a label which i want to popualte with the users name so i reference the get propertie on the ExamMethods class but its null? how can this be possible? what am i missing?
This is the code for the behind home.aspx page
public partial class Home : System.Web.UI.Page
{
Hashtable UpdateUser = new Hashtable();
protected void Page_Load(object sender, EventArgs e)
{
Methods.ExamMethods obj_UserDetails = new Methods.ExamMethods();
if (Request.QueryString["uid"] == null)
{
Response.Redirect("Login.aspx");
}
else
lblUserName.Text = obj_UserDetails.FirstName;
}
Is it because I have used reponse.redirect from the login page to the home page that the get set methods are nothing?

Variables aren't shared among web pages when you are working with web pages. As you might know HTTP is a stateless protocol.
So how do I do this?
You need state management. You need a way to pass the information around. From what I see, Sessions seems to be best place to store this data that you require to use in multiple pages.
But sessions are not the only state management option you have. You have many more depending on what you want to store, how much you want to store and where/when you want to access them.
I suggest you read up on ASP .NET State Management also read up on recommendations to understand which state management feature to use in which scenario.

In Page_Load method you're creating a new instance of Methods.ExamMethods() each time so all of its properites are not initialized. After you are redirected to login page, perform login and are redirected back, Page_Load is executed again and a new instance of the class is created.
The preffered way of doing it would be just reading user's data from database based on uid when you have it defined in theQueryString.
protected void Page_Load(object sender, EventArgs e)
{
Methods.ExamMethods obj_UserDetails = new Methods.ExamMethods();
if (Request.QueryString["uid"] == null)
{
Response.Redirect("Login.aspx");
}
else
{
if (!Page.IsPostback)
{
//read value of uid parameter
int uid = Request.QueryString["uid"];
//access database to retrieve user's details
obj_UserDetails = GetUserDetails(uid);
lblUserName.Text = obj_UserDetails.FirstName;
}
}
}
It's also worth monetioning that you can use Page.IsPostback attribute to fill controls with user's data. On postbacks ViewState mechanism should preserve controls' contents.
There are also some other mechanisms that allow you to pass data between pages, like Session state. This can be used if you need user details on more pages than just those two. This way you don't have to access the database to often.
Using Server.Transer() method to redirect user to another page and using PreviousPage object can give you access to other page as well, but I suppose using QueryString and reading data directly on Home page would be the most appropriate in your case.
Links that can be helpful:
ASP.NET Session State Overview
Understanding ASP.NET View State
HttpServerUtility.Transfer method

Instances don't stay alive when you browse through pages on the web, you can store things you need in a session and get it when the new page loads
you can do this when you need to store the data
Session["data"] = new Data("SomeData");
and you can do this when you need the data again
var data = Session["data"] as Data;
if(data != null)
//do something with the data

Related

Issue with WebMethod being Static in C# ASP.NET Codebehind

Due to a problem caused by having multiple forms on a single page, I used an AJAX call to a WebMethod to submit my form instead of using ASP controls. However, in doing this, the previous method I had used to create a new entry into my database no longer works because a WebMethod must be static.
I have authenticated my user already using ASPX authentication, and am trying to retrieve the username and ID of that user with codebehind. The user has already been authenticated on Page_Load, but it seems I cannot access this information through my WebMethod. Is this possible to do inside of a static WebMethod? Thank you for all of your help in advance!
[WebMethod]
public static void CreateJob()
{
Submit_Job();
}
public static void Submit_Job()
{
if (Page.User.Identity.IsAuthenticated)
{
try
{
string username = Context.User.Identity.Name;
}
catch
{
Context.GetOwinContext().Authentication.SignOut();
}
}
var manager = new UserManager();
var usernameDatabase = new ApplicationUser() { UserName = username };
usernameDatabase = manager.Find(username, "password here");
if (usernameDatabase != null)
{
IdentityHelper.SignIn(manager, usernameDatabase, isPersistent: false);
string jobTitle = Request.Form["jobTitle"];
using (var ctx = new CreateUserContext(ConfigurationManager.ConnectionStrings["myconnectionstring"].ConnectionString))
{
Job job = new Job()
{
job_title = jobTitle
};
ctx.Jobs.Add(job);
ctx.SaveChanges();
}
}
}
Edit:
There are errors for example with Page.User.Identity.IsAuthenticated -- Page, Context, and Request all appear that they cannot be static.
The specific error:
(An object reference is required for the non-static field, method, or property 'Control.Page') as well as with Context and Request.
Moving it from a simple comment
I had the same issue recently.
Luckily, whenever a user signs in our application, we store the user information encrypted into a session variable, so I retrieve that information, pass it to our user's class constructor, which decrypts it and I can use my logged in users info without a hassle.
So, my solution is to store the users info in the Session, but be careful what you store. Maybe serialize the users object and store in the session, then, whenever you need it
public void Page_Load()
{
// Retrieve authenticated user information
UserClass userObject = GetUserCredentials();
// Call a method that turns the authenticated user object into a string that contains the users session information. Given the sensivity of this information, might want to try to encrypt it or offuscate it. Store it in a session variable as a string
Session["UserContext"] = userObject.SerializeUser()
/* rest of the page code goes here */
}
[WebMethod(EnableSession=true)]
public static void CreateJob()
{
Submit_Job();
}
public static void Submit_Job()
{
// Lets get the authenticated user information through the session variable. Due to the static nature of the method, we can't access the Session variables directly, so we call it using the current HttpContext
string serializedUserInfo = )HttpContext.Current.Session["UserContext"].ToString();
// Let's create the users object. In my case, we have a overcharged constructor that receives the users serialized/encrypted information, descrypts it, deserializes it, and return a instance of the class with the deserialized information
UserClass userObject = new UserClass(serializedUserInfo);
// Do whatever the method has to do now!
}
On the subject of serialization, a quick google search with "c# object serialization" will bring you several good matches. XML and JSON are 2 of the most used kind of serialization, specially on web methods. Binary serialization is a good option to also obfuscate information of the logged in user

what is used in windows app on the place of Session?

i am new to windows programming, as we use Store user's details in Session when user successfully logged into a web application and check the session in master page every time, if it will null then redirect the user to login page. I want to do the same thing in Windows application, i have created a login form: the code is written below:
private void btnLogin_Click(object sender, EventArgs e)
{
clsLogin obj = new clsLogin();
DataTable dtLogin = obj.Login_Check(txtUserName.Text.Trim(), txtPassword.Text.Trim());
if (dtLogin.Rows.Count > 0)
{
if (dtLogin.Rows[0]["result"].ToString() == "3")
{
lblMessage.Text = "Password does not matched";
}
else
if (dtLogin.Rows[0]["result"].ToString() == "2")
{
lblMessage.Text = "User does not exists";
}
else
{
Staff.Home home = new Staff.Home();
this.Hide();
home.Show();
}
}
}
}
Now what i want to do is: store the user info some where and when user click on Log off then it will destroy that session and it will open the Login form.
i know it is a very silly question, as i am new to windows programming its tough for me, please help.
Apart from the obvious issues with the code:
Direct access to rows by index
Login being done in the event handler directly
You should have separate login service and data access service
I would:
Create a login service that maintains the current logged in user details and performs the authentication itself.
Create a data access service that the login service can call to access the datastore
Then in your event handler you just need to call:
if (loginService.Authenticate(username, password))
{
// Do your UI handling here
}
then the loginService will have a .CurrentUser property for example and you can go from there.
e.g.
public class LoginService
{
private User _currentUser;
public bool Authenticate(string username, string password)
{
if (_currentUser != null)
{
Logout();
}
else
{
var user = DataAccess.Get("users").SingleOrDefault(u => u.Username = username);
if (user == null)
{
throw new Exception("No user with that username found");
}
if (password == user.Password)
{
_currentUser = user;
return true;
}
else
{
return false;
}
}
}
public User CurrentUser
{
get { return _user; }
}
}
In a Web application it is supposed that there are multiple clients connected to the single server; you should use Session to distinguish between them and to pass data to each of them "there and back again". For a desktop application this problem does not exist at all - there is exactly one user and his data is all here: you do not need some special mechanism like Session for it.
This means that you may use a number of different approaches to pass data from your form. In your example it seems more logical to pass data to your "home" form directly, either through constructor
else
{
var userData = .... (txtUserName.Text);
Staff.Home home = new Staff.Home(userData);
this.Hide();
home.Show();
}
or through a property
else
{
var userData = .... (txtUserName.Text);
Staff.Home home = new Staff.Home();
home.UserData = userData;
this.Hide();
home.Show();
}
This is only an example, there are a lot alternatives - just think about this "single user, always on site" model.

Passing a value to a global variable for reference with WinForms (C#) and SQL Connection

I need two global variables to be accessed by multiple winforms at various stages.
The first is in regards to a distinct user, after logging in to the app,
other winforms need to get data from sql server tables based on the user who logged in.
SqlCommand cmd = new SqlCommand("SELECT * FROM regClient WHERE client_ID = **[GLOBAL VARIABLE]**", con);
The second follows this in that the user can log in as either a Client or Student. Different statements need to be called based on this. This value is set by radiobutton on the login window.
So if radClient is checked set global to 'client', if radStudent is checked set global to 'student'
then with other winforms can call select statements or enable/visible based on what the global is.
I believe I can store variables in Programs.cs but I'm not sure.
Create a User class:
public class User
{
public enum eStatus
{
Client,
Student
}
public static eStatus Status { get; set; }
public static string Name { get; set; }
}
You didn't say what the one variable is, so I guessed it was some kind of identifier like their name.
You can set the User's status with:
User.Status = User.eStatus.Client;
and the name with:
User.Name = "Charlie";
You can access and set the values from anywhere.
Comment response:
The if would look like:
if (Program.User.Status == Program.User.eStatus.Client)
{
// commands
}
else // if (Program.User.Status == Program.User.eStatus.Student)
{
// commands
}
You don't need the second if since there are only two values User.Status can have.

OpenId - how to use checkid_immediate and x-has-session?

The documentation doesn't tell much about those two parameters. I understand they somehow related to log in status checking.
I want to check if a user is currently logged in the browser (Meaning, signed in with google, and checked "keep me logged in" )
I want to be able to differentiate between to states :
A user is logged in the browser (meaning, signed in with Google for
example, and check "Keep me logged in") and that user already
approved my app.
Any other state. (user is not logged in . user logged in but with an
identity he didn't approved yet... etc.)
If I know I am in the first state, I don't need to "show" the popup (I give it top=9999 left=9999)
I am trying to figure out the two states with this code. This needs to be done without any user interaction or any visual cue.
public partial class WebForm1 : System.Web.UI.Page
{
protected string Url { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
var parameters = new Dictionary<string, string>();
parameters.Add("openid.ns", "http://specs.openid.net/auth/2.0");
parameters.Add("openid.claimed_id", "http://specs.openid.net/auth/2.0/identifier_select");
parameters.Add("openid.identity", "http://specs.openid.net/auth/2.0/identifier_select");
parameters.Add("openid.return_to", "http://localhost:17556/redirect.aspx");
parameters.Add("openid.realm", "http://localhost:17556/");
parameters.Add("openid.mode", "checkid_immediate");
parameters.Add("openid.ns.ax", "http://openid.net/srv/ax/1.0");
parameters.Add("openid.ax.mode", "fetch_request");
parameters.Add("openid.ax.type.email", "http://axschema.org/contact/email");
parameters.Add("openid.ax.required", "email");
parameters.Add("openid.ns.ui", "http://specs.openid.net/extensions/ui/1.0");
parameters.Add("openid.ui.mode", "x-has-session");
string OpenIdEndpoint = https://www.google.com/accounts/o8/ud;
var url = CreateUrlRequest(OpenIdEndpoint, parameters);
WebClient wc = new WebClient();
var res = wc.UploadString(url, "");
}
public string CreateUrlRequest(string i_Url, Dictionary<string, string> i_Parameters)
{
return string.Format("{0}?{1}", i_Url, string.Join("&", i_Parameters.Select(kvp => string.Format("{0}={1}", kvp.Key, kvp.Value)).ToList()));
}
}
running this code, a callback is sent to redirect.aspx, but the query string doesn't have any information about the states I am interested in. It contains openid.mode=setup_needed among other things.

How do I maintain user login details in a Winforms application?

Hi can I'm very new to windows forms. Here I want to maintain state (like session in web applications) in windows forms.
Actually i want to store user login details in session. But i think there is no concept of session in winforms. So what is the alternative method to handle this type of situation.
Regards,
Nagu
There is no concept of Session variables in windows forms. What you can do is:
Create a internal class that holds the User name and password and any other variables and enumerations needed across the application (Something like Common.cs). These can be accessed through public properties across the application.
Have a parameterized constructor for all the forms and send the user name and the password whenever you are showing the form.
public class MyForm : Form
{
private string userName;
private string password;
}
Since windows forms are statefull (opposed to stateless for web forms), you can just use a field in your Form class.
You need to think more in terms of scope than session; as long as an object remains in scope you will be able to pull values from its public properties/fields.
In your case it would make sense to store the user details in a static class:
public static class LoginInfo
{
public static string UserID;
}
Now you can access the UserID simply from anywhere in your code:
MessageBox.Show(LogInfo.UserID);
In winforms you can use variables that are exposed to other forms through methods or properties.
You can also use static variables.
In the following example, you would have a controller for each window or group of windows. The controllers would be passed to one another depending on how they need to collaborate (what knowledge they need to share, etc). The important thing is to keep your application state in the controllers and limit the windows to handling user input and events.
// pseudocode, because I do not know WinForms that much
class MainController
{
private Guid securityToken;
public Guid SecurityToken
{
get { return securityToken; }
set { securityToken = value; }
}
}
class LoginWindowController
{
MainController mainController;
LoginWindow loginWindow;
public LoginWindowController(MainController mainController)
{
this.loginWindow = new LoginWindow(this);
this.mainController = mainController;
}
public void Show()
{
loginWindow.IsVisible = true;
}
public void HandleLogin()
{
Guid token =
myobject.Authenticate(loginWindow.Username, loginWindow.Password);
if (token != Guid.Empty)
{
mainController.SecurityToken = token;
}
}
}
In reply to your comment to my first reply:
You are creating the new instance of the Login form. How is that supposed to have values. It is a Login form and hence I believe you will be closing it as the user enters user name and password and clicks OK or whatever.
Then, there is no way you can get the values from the Login form as it is closed. If you need to stick to this approach, this could be a way:
Do not close the Login form, just hide it.
Pass the current instance to the next form. Like this:
In Login form:
NextForm nxt = new NextForm(this);
The constructor of NextForm will look like:
public NextForm(LoginForm frm){
// Code here
}
Now in NextForm, you can access the properties through "frm".
from a program i was using with a login form to store global variables and to store the password as a secure string. Within the program I am able to "run as" a specific user when I call processes. You can use it for other things besides process.start.
//to run process as another user
//create these global variables on the first
//form or piece of code in your program
class usernameGlobalVariable
{
public static string var = "";
}
class passwordGlobalVariable
{
public static SecureString var;
}
// use these as event handlers for text fields
//for your login form
private void usernameTextBox_TextChanged(object sender, EventArgs e)
{
usernameGlobalVariable.var = usernameTextBox.Text;
}
private void passwordTextBox_TextChanged(object sender, EventArgs e)
{
SecureString passWord = new SecureString();
foreach (char c in passwordTextBox.Text.ToCharArray())
{
passWord.AppendChar(c);
}
passwordGlobalVariable.var = passWord;
}
//put this on form that launches program
//this assigns variables for process.start
//change fileName to path and name of program
// use \\ in paths
string fileName = "c:\\hdatools\\Ping2.exe";
string arguments = "";
string domain = "domain";
//start the process
//put this on the page along w the above variables that
//launches the app as another user
//the .var variables are global
{
Process.Start(
fileName,
arguments,
usernameGlobalVariable.var,
passwordGlobalVariable.var,
domain);
}
It's unclear to me whether you are talking about a web application or a stand along application based upon one of your responses. If you are talking about a web application, you can use the Session properties on the Page object.
It would set the variables like this:
Session["username"] = "Username";
Session["fullname"] = "User's full name";
You could then access like:
lblGreetings.Text = "Hi " + Session["fullname"];
Is that what you were after?

Categories