i have an asp.net mvc4 application, in which i have this class:
public class Internaute {
public int Id { get; set; }
public string Name { get; set; }
public string Login { get; set; }
public string Password { get; set; }
}
then, when a user connect, i get its informations by storing it in a session variable like this:
Session["user"] = myInternaute;
And i used these informations ,for example, like this:
#{
Internaute myInternaute = (Internaute)Session["user"];
string login = myInternaute.Login;
string pwd = myInternaute.Password;
}
I test the autorization of the user to acces by
Internaute myInternaute = (Internaute)Session["user"];
if(myInternaute == null) return RedirectToAction("Index");
So i have these questions:
Is it a good way to proceed by a session variable?
Is there another idea to do this, because the session were lost.
Does this idea have some advantages?
Thanks,
Is it a good way to proceed by a session variable?
Yes your code looks good except you should check for null whenever you get the value from Session to make sure its not null. Also, do you really need Password stored in session? Its not a good idea to store it as string in Session.
Is there another idea to do this, because the session were lost.
If I understand your question correctly, yes your session data will be lost on Session timeout. If you want you can increase the session timeout in the web.config file.
Does this idea have some advantages?
You will have some basic data about the user readily available in Session instead of querying the database but you should make sure that the Internaute class remains lightweight.
Related
I am trying to use some methods within set/get accessors on properties of classes generated by entity framework. Purpose is to encrypt the field before saving to DB and Decrypt the fields before reading from DB.I am doing it at the POCO class level so that the encryption-decryption happens while interacting with DB itself and I dont have to scriible through a lot of code. Is the POCO class the best interface to do that?
Code builds successfully, but I get a .Net Framework error when I execute it and the visual studio process is killed eventually.
I am not sure, I might be making some very basic error, but haven't been able to get down to it. Any suggestions will be greatly appreciated !
[Table("Users")]
public class User
{
[Key]
[Required]
public Int32 UserID { set; get; }
[Required]
[MaxLength(50)]
public String UserName // This is where I am using encryption decryption methods
{
set
{
this.UserName = NewEncryptionMethod(value);
}
get
{
return NewDecryptionMethod(this.UserName);
}
}
[Required]
public Int32 CustID { set; get; }
The reason that it's failing right now is because you're running into an infinite amount of calling the get part of UserName since you're trying to grab the value by trying to grab the value and decrypting it. This will cause an overflow error eventually.
Your solution to this is to leave the records in the database as they are, bring them over, and then use a ViewModel class that will contain the decrypted data. When you want to go back to the database, simply encrypt the value in the ViewModel and push that value to the database.
I don't say that the way you are doing the work is good , first thing i can say is that you have infinite recursive call.
Solution:
private string _username;
[Required]
[MaxLength(50)]
public String UserName // This is where I am using encryption decryption methods
{
set
{
_username = NewEncryptionMethod(value);
}
get
{
//you have to deal with a null username here is a bad but quick solution
_username = _username ?? string.Empty;
return NewDecryptionMethod(_username);
}
}
You can keep in UserName raw, insecure data. But make this property internal.
// map me
internal string UserName { get; set; }
And secure it using another property but public:
// don't map me
public string SecureUserName
{
get { return Encrypt(UserName);
set { UserName = Encrypt(value); }
}
Another way is to use a separate class for this purpose, say SecureUser or UserViewModel:
public class SecureUser
{
private readonly User _user;
public SecureUser(User user)
{
_user = user;
}
public string UserName
{
get { return Encrypt(_user.UserName);
set { _user.UserNAme = Decrypt(value); }
}
}
I am developing an ASP.NET MVC 4 application. userMenus is a static variable that is loaded every time a user logs in.
public class MenuCL
{
public static List<UserMenu> userMenus = new List<UserMenu>(); // the static variable
}
public class UserMenu
{
public decimal MenuID { get; set; }
public string MenuName { get; set; }
public string Controller { get; set; }
public bool Permission { get; set; }
}
I use that static variable to check whether or not the logged in user has permission to a menu/controller in a custom authorize filter.
It works fine when a single user is logged in, but when two or more users are logged-in, it's all messed up, I mean the error page("you don't have access to this page") is displayed to a user that has permission to the menu/controller.
Only now I realized it's the static variable that is causing all the trouble, after I read this :
The static variables will be shared between requests. Moreover they will be initialized when application starts, so if the AppDomain, thus application gets restarted, their values will be reinitialized.
So I need a replacement for this static variable. Anyone has any suggestion?
You can still use a static field which is a property that provides access to a session variable.
public static List<UserMenu> UserMenus
{
set
{
Session["UserMenus"] = value;
}
get
{
return Session["UserMenus"] == null ? new List<UserMenu>() : (List<UserMenu>) Session["UserMenus"];
}
}
In order to get this working on a web farm which uses a session state server (or sql server), you need to put [Serializable] attribute on top of UserMenu.
I don't think, this way you need to modify your code very much.
My question is, why do you want to use static variable? Do you want to share the values across the application? In this case you can better use session.
Updated
Assume lst as a non static List of UserMenu. Then you can use the following method to store it in session and get it bak whenever you want.
To store
Session["usemenulist"] = lst;
To get it back
try
{
lst = (List<UserMenu>)Session["usemenulist"];
}
catch
{
}
Note
If you are getting the values from the database lo load it to the List for the first time, then you can query database to get it from the database whenever you want, instead of storing it in the session. (This is another option apart from Session, you may try this way also if you want.)
When my user in the students Role login to the system, he can select various classes that he's enrolled. I already have a filter that'll redirect him to the select class page so he must select a class to access the system, and change it anytime he wants and the whole system's context will change.
As for now, i'm storing IdClass in the session variable, using the code below, and the system uses it to filter all the related queries and functions, like showing all the lessons from the current class. My question is: is this a good practice? Is this right or is there any better and efficient way? I'm trying to follow patterns.
[Serializable]
public sealed class Session
{
private const string SESSION_FOO = "STUDYPLATFORM_GUID";
private Session()
{
this.IdClass= 0; // Construct it to 0 so it evaluate as there's no Class selected.
}
/* This is the session's public IdClass that
i can get and set throughout the application. */
public int IdClass { get; set; }
public static Session Current
{
get
{
if (HttpContext.Current.Session[SESSION_FOO] == null)
{
HttpContext.Current.Session[SESSION_FOO] = new Session();
}
return HttpContext.Current.Session[SESSION_FOO] as Session;
}
}
}
I don't even know how to word this question...
I am using the newish asp.net identity provider. I would like to be able to pull in certain data from the logged in user on just about every view of my site. My simplified model is this:
User.cs
public class User : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
....
}
In razor views, I get check to see if someone is logged in and then use:
#User.Identity.GetUserId()
Which will obviously return my username. I would like to make a way I could call #User.Identity.GetUserFirstAndLastName() or something like that. Is there a way I can add a call like that? I would really hate to have to ViewBag the value for every single view I have.
Thanks to wdosanjos for pointing me to extenstion method. After reading the link and googling some more I came up with this:
public static class IdentityApplicationUserExtension
{
public static User GetApplicationUser(this IIdentity identity)
{
var manager = new UserManager<User>(new UserStore<User>(new MyDbContext()));
return manager.FindById<User>(identity.GetUserId());
}
}
User is the ApplicationUser class.
In a razor view all i need to do is this:
#User.Identity.GetApplicationUser().AnyColumnFieldHere
Super simple after all!
I am building a class to store User ID and User Role in a session. I'm not sure how this class will behave when multiple users are on the site at the same time. Does anyone see a problem with this?
public static class SessionHandler
{
//*** Session String Values ***********************
private static string _userID = "UserID";
private static string _userRole = "UserRole";
//*** Sets and Gets **********************************************************
public static string UserID
{
get
{
if (HttpContext.Current.Session[SessionHandler._userID] == null)
{ return string.Empty; }
else
{ return HttpContext.Current.Session[SessionHandler._userID].ToString(); }
}
set
{ HttpContext.Current.Session[SessionHandler._userID] = value; }
}
public static string UserRole
{
get
{
if (HttpContext.Current.Session[SessionHandler._userRole] == null)
{ return string.Empty; }
else
{ return HttpContext.Current.Session[SessionHandler._userRole].ToString(); }
}
set
{ HttpContext.Current.Session[SessionHandler._userRole] = value; }
}
}
The code you posted is the exact replica of some code we have here.
It has been working fine for 2 years now.
Each users access is own session. Every request made to the server is a new thread. Even though 2 request are simultaneous, the HttpContext.Current is different for each of those request.
You'll get a new session for each connection. No two users will ever share session. Each connection will have its own SessionID value. As long as the user stays on your page (doesn't close the browser, etc.) the user will retain that session from one request to the next.
This will work fine for mutiple users accessing your application as there will be different sessionid generated for all deffrent users accessing application concurrentely. It will work in similar way if you have defined two different session variables in your system.
It will be like wrapping tow session states using static wrapper class SessionHandler.