MVC Session for storing user information vs DB call - asp.net-mvc

I have a user details area that is split out on to about 6 different pages (details, contact, preferences, etc). I need to have access to all of the user details after login.
I was going to add the user details to a Session like this after login so that I could access them all from the different pages without having to call the database on each page;
Session["name"] = name;
Session["bla"] = bla;
However I've googled and some people talk about saving the session to a database, which sounds like i may as well not use it. The users may not access every page or require access to all of this information, so it could be seen as a bit needless to add them all to a Session.
Is there a recommended practice for storing user information like this? I also have an ID that needs to be shown on every page. Perhaps something like this is better for a session and the more detailed info pages to keep with their own database calls?
.
EDIT: I am using Umbraco 7.2.8 and am getting the member details from the MemberService. I am worried that it hits the database each time though. My code to get the Member details and also the custom member properties (currently in each controller) is;
// Get the details of the user currently logged in
var profileModel = Members.GetCurrentMemberProfileModel();
// Get the custom properties for the member
var member = memberService.GetByUsername(profileModel.UserName);
model.Firstname = profileModel.Name;
model.Email = profileModel.Email;
model.specialID = member.Properties["specialID"].Value.ToString();
Any pointers would be great!

If you use the built in Umbraco Member service (link 1, link 2) to manage your users, you'll have a relatively simple way to get current logged in member. It's also easy to manage the member profiles with custom data fields and so on. No need to think too much about sessions and such.
Edit: take a look in here - specifically the GetCurrentPersistedMember() method - Umbraco is using caching to save current member

There are three popular ways to store the data in memory
1) Caching
2) Session
3) Static Classes
Out of above three I will always prefer Caching, as numerous articles suggested and I too agree that Sessions are comparatively slow than Caching & Static classes. I would always prefer caching over sessions.
But whatever you use, make sure that you are initializing them at single place, so that all the sessions and caching used in whole application is known to every developer. This will help in code re-usability & reduces the duplication of initializing the same value again in system. It will also help in code-maintainability.

Related

Laravel 5.1 Passing data (controller -> view)

I'm new to Laravel, I want to understand what is the best approach to share values from controllers to views: I have found few ways of doing it :
view()->share('variable_name',$value);
session(['variable_name'=>$value]);
return view('viewname')->with('variable_name'=>$value);
Is there any difference between these ways?
Also, is it a good practice to share data from the model(from design point of view)?
Thanks
1) The best and valid approach, passing data from controller to view is
return view('viewname')->with('variable_name'=>$value);
data will be accessible in specific page views
2) While this is also valid approach, but this case is used, when you want to share your data in all views on any page you access
view()->share('variable_name',$value);
the above line means, when you access any page, in all pages your variable_name will be available eg:
welcome
contact us
about us
gallery
admin/listing etc
3) session() is used for storing small amount of information across the all website pages. eg: we store, user basic information, last login time, redirect url etc(it depends upon requirement), be default session has some expiry time, around 20min, means if you don't do any activity, your session will be expire.
I hope that make sense for you

Caching lookups in MVC, default expiration?

I am caching lookup data in my mvc application, I have the following code:
// GET: Category Types
public JsonResult GetAuditGrants(int auditID)
{
AuditDAL ad = new AuditDAL();
if (System.Web.HttpContext.Current.Cache["AuditGrants"] == null)
{
System.Web.HttpContext.Current.Cache["AuditGrants"] = ad.GetAuditIssueGrants(auditID);
}
var types = (IEnumerable<Grant>)System.Web.HttpContext.Current.Cache["AuditGrants"];
return this.Json(types.ToList());
}
If expiration is not set, by default when does the data expire in cache? Is recommended and should it be stored in the webconfig for consistency for lookup data in my app?
To answer your first question, we can consult MSDN. According to its documentation, adding an object using the Item property (or indexer) is equivalent to calling the Insert method, whose documentation states:
The object added to the cache using this overload of the Insert method
is inserted with no file or cache dependencies, a priority of Default,
a sliding expiration value of NoSlidingExpiration, and an absolute
expiration value of NoAbsoluteExpiration.
Your second question is really pretty application-specific. The best practice is to profile your application. If your application is experiencing a ton of cache-misses and your cache stays small, then you might want to extend the expiration sliding window by using one of the Add or Inserts overloads that give you that control. In that case, storing your selected parameters in the app settings seems like a good idea.
One thing to remember about this cache, however: it is per-app domain. If you have multiple web frontends, or even an IIS server configured to launch more than one worker process for your app, then you may not be getting the most out of your caching strategy. In that case, you might need to use something that can offer persistence to multiple instances of your app. We use Redis, but there are many other options.

Is it possible to set a scope to a domain class?

I'd like to know if it's possible with grails to specify a scope for the domain classes.
Few words to explain how my application is working at the moment:
- database access is done through an external "module" using SQLJ. This module is user by controllers in my grails app.
- a user ask for specific information submitting forms -> request submitted to the external module -> information extracted from the database -> information loaded into grails mem DB (HSQL) -> information displayed in views.
It works fine in development environment as i'm the only one using the application. But i'm wondering how the application would behave with two or more users. I mean, do the information loaded into grails memory database will be shared between users or not? And how not to shared information requested by one user with the others?
Thanks in advance for any help about this subject.
Regards.
All data in the database is shared across all users of the grails application. You would have to write a custom query to limit the data returned to a specific user. Based on your application maybe something similar to the following.
class DomainClass1 {
//fields you get from SQLJ go here
int userId
}
To get data into an instance of your domain class.
def domInstance=new DomainClass1()
domInstance.loadFromSQLJ() //call the SQLJ module and put it's data in the domain class
domInstance.userId=5 //assign the user associated with this info
domInstance.save()
Then when you want to display info for the user with the userId 5
def domInstance2=DomainClass1.findByUserId(5)
//Do stuff with domInstance2
It will be shared between all users.
But it depends on you, as for any other database, there must be some criteria (db column) by which you can choose only information related to current user.
In our project, we overrode domain classes' get(), list() that take into account domain aggregate root (a User or whatever), and also check all the named queries.
This leaves off all the other means of accessing instances, like findBy*(), criteria, findWhere() (though you can also override the dynamic methods), or HQL, but anyway reduces the amount of security review by 80%.
Suddenly it turned out to be OK to use DomainClass.list() in scaffolding.

how do I efficiently implement SO-like favorite and voting feature?

I'm using ASP.NET MVC, SQL Server 2008 and Forms Authentication. Suppose I am building a question-answer site like SO.
Here is the issue I am running into:
Users can view almost all the questions when not logged in, like they can on SO. Question-fetching query etc is almost written.
Now, if a user is logged in, he should also be able to tell whether he has already voted or "favorited" this question, like on SO.
Do I go back and rewrite all my
queries to include userIdInt
parameter even when the user is
anonymous just to know this
information?
Or when a user logs
in, I store what all he has voted on
and keep track of that throughout
his session?
Both seem cumbersome, but 1) seems more efficient at least. Anybody know how SO does this or more efficient way?
I think it doesn't keep track of whether the user has voted, but it does seem to keep track of whether the user has "favorited" that question.
You could use multiple interfaces, one for anonymous access, and one for authenticated access, and perform different queries for each:
http://en.wikipedia.org/wiki/Interface_segregation_principle
// Just example code - not asp.net-mvc
interface IAnonymousReader
{
IEnumerable<Answer> GetAnswers(int page, int countPerPage);
}
interface IAuthenticatedReader
{
IEnumerable<AuthenticatedAnswer> GetAnswers(int page, int countPerPage,
int userId);
// An alternative here is to get userId from concrete class, and pass in ctor
}
This would require that you write multiple queries, or that you get back data that you just throw away. You can avoid code duplication by constructing your query programatically. You could avoid writing the queries to begin with by using ORM.
As for the data, you could normalize the data, so that voting information is in a separate table, but still bound to the answer. When you're doing the query for anonymous users, simply don't join/query that table.

Nhibernate (and ORMs in General): work with Objects or ObjectIds?

This is something that has been pulling at me for a while. Consider a (MVC type) web application with an ORM (e.g. Nhiberate) as the data access layer.
On one hand - the OOP/Rich domain model hand - I feel I should be passing around (references to) the real objects I am talking about.
On the other hand - the DB/Web App hand - I feel that it is easier and more efficient just to pass the integer Ids of the objects rather than the object themselves.
Consider an ecommerce catalogue type application:
The user is logged in and navigates to a product page.
They post a comment.
The controller action tasked with persisting this comment has 3 pieces of information: a) The user id (from the auth cookie or wherever), b) The product id (probably from the querystring), and c) the comment text.
Now, what what is best practice here? Is it really worth inflating the user and product objects (e.g. by getting them from the repository, with all the DB work that entails) when we know that all they will be used for is so the ORM can read their IDs and set the appropriate foreign keys in the DB table that stores the comments?
What are peoples views on this? Perhaps web apps should be given a little more leway than other apps, due to their stateless nature? I imagine there will be 'it depends' answers, but maybe some people are purists about the issue.
This is a general question which probably is applicable to many platforms, but if giving examples I would prefer them to be ASP.NET MVC if possible.
Thank you.
NHibernate has the load operation (as opposed to doing a get) exactly for this reason.
session.Save(
new Comment
{
Text = commentTextFromScreen,
User = session.Load<User>(userID),
Product = session.Load<Product>(productID)
}
};
In the above example, you are telling NHibernate: I know these already exist in the database, so don't bother selecting them right now. NHibernate will return proxy objects for them and a select won't happen against the database as long as you don't attempt to access any properties on the objects.
For more info check out Ayende's blog post: The difference between Get, Load, and query by id.

Resources