does Session.Clear(); clears all sessions data - asp.net-mvc

I Want to clear one session Data but it's clearing both Sessions data. below is my 2 MVC action methods which are used to clear Session data.
1)
public int Clearsesson()
{
int i = 0;
List<Wish_Product> products = new List<Wish_Product>();
if (**Session["WishItem"]** != null)
{
Session.Clear();
i = 1;
}
else
{
i = 0;
}
return i;
}
2)
public int Clearsesson2()
{
int i = 0;
List<Cart_Product> products = new List<Cart_Product>();
if (**Session["CartItem"]** != null)
{
// Session.Remove("CartItem");
Session.Clear();
i = 1;
}
else
{
i = 0;
}
return i;
}
So like this I am storing Data in two Sessions but when I run this asp.net MVC Action method to clear One session data, it automatically clears second one Session Data too.
Why so like this? Please make it clear to me why it's happening.
Or what I've to do to solve this problem?

The short answer is yes, on the current collection.
According to ASP.NET documentation, HttpSessionState.Clear method removes all keys and values from currently active session state collection (it doesn't destroy user's session state base), so that both Session["WishItem"] & Session["CartItem"] values are cleared together from collection when the method is executed, but the session state base kept alive.
There are 2 different session collection keys in this case & actually both of them using same session state. To clear single session data, there are 2 different ways:
1) Remove session key using Session.Remove.
Session.Remove("WishItem");
2) Assign null value to the session state based with its key.
Session["WishItem"] = null;
The difference between them is that the former deletes both keys and values so that it won't appear as key-value pair in session collection anymore, and the latter overwrites current collection value with specified key but the key name still unchanged.
Therefore, you can remove each session data separately without clearing another session key like this:
public int ClearSession()
{
int i = 0;
// other code logic
if (Session["WishItem"] != null)
{
// only WishItem key has cleared
Session.Remove("WishItem");
i = 1;
}
// other code logic
}
public int ClearSession2()
{
int i = 0;
// other code logic
if (Session["CartItem"] != null)
{
// only CartItem key has cleared
Session.Remove("CartItem");
i = 1;
}
// other code logic
}
Note that each authenticated user always be assigned with one session state base, hence using Session.Clear removes all existing key-value pairs stored in session collection for current user (doesn't affect other user's session state).

Related

Mahout Recomendaton engine recommending products and with its Quantity to customer

i am working on mahout recommendation engine use case.I precomputed recommendations and stored in database. now i am planning to expose with taste rest services to .net.i had limited customers and products.it is distributor level recommendation use case.my question is if new distributor comes in ,how would i suggests recommendations to him.and also how would i suggest the Quantity of Recommended product to each distributor.could you people give me some guidance.am i going to face performance issues..?
One way is, when new user comes, to precompute the recommendations from scratch for all the users or only for this user. You should know that this user might change the recommendations for the others too. Its up to your needs frequently do you want to do the pre-computations.
However, if you have limited number of users and items, another way is to have online recommender that computes the recommendations in real time. If you use the FileDataModel, there is a way to get the data from the new user periodically (See the book Mahout in Action). If you use in memory data model, which is faster, you can override the methods: setPreference(long userID, long itemID, float value) and removePreference(long userID, long itemID), and whenever new user comes and likes or removes some items you should call these methods on your data model.
EDIT: Basically you can get the GenericDataModel, and add this to the methods setPreference and removePreference. This will be your lower level data model. You can wrap it afterwards with ReloadFromJDBCDataModel by setting your data model in the reload() method like this:
DataModel newDelegateInMemory =
delegate.hasPreferenceValues()
? new MutableDataModel(delegate.exportWithPrefs())
: new MutableBooleanPrefDataModel(delegate.exportWithIDsOnly());
The overridden methods:
#Override
public void setPreference(long userID, long itemID, float value) {
userIDs.add(userID);
itemIDs.add(itemID);
setMinPreference(Math.min(getMinPreference(), value));
setMaxPreference(Math.max(getMaxPreference(), value));
Preference p = new GenericPreference(userID, itemID, value);
// User preferences
GenericUserPreferenceArray newUPref;
int existingPosition = -1;
if (preferenceFromUsers.containsKey(userID)) {
PreferenceArray oldPref = preferenceFromUsers.get(userID);
newUPref = new GenericUserPreferenceArray(oldPref.length() + 1);
for (int i = 0; i < oldPref.length(); i++) {
//If the item does not exist in the liked user items, add it!
if(oldPref.get(i).getItemID()!=itemID){
newUPref.set(i, oldPref.get(i));
}else{
//Otherwise remember the position
existingPosition = i;
}
}
if(existingPosition>-1){
//And change the preference value
oldPref.set(existingPosition, p);
}else{
newUPref.set(oldPref.length(), p);
}
} else {
newUPref = new GenericUserPreferenceArray(1);
newUPref.set(0, p);
}
if(existingPosition == -1){
preferenceFromUsers.put(userID, newUPref);
}
// Item preferences
GenericItemPreferenceArray newIPref;
existingPosition = -1;
if (preferenceForItems.containsKey(itemID)) {
PreferenceArray oldPref = preferenceForItems.get(itemID);
newIPref = new GenericItemPreferenceArray(oldPref.length() + 1);
for (int i = 0; i < oldPref.length(); i++) {
if(oldPref.get(i).getUserID()!=userID){
newIPref.set(i, oldPref.get(i));
}else{
existingPosition = i;
}
}
if(existingPosition>-1){
oldPref.set(existingPosition, p);
}else{
newIPref.set(oldPref.length(), p);
}
} else {
newIPref = new GenericItemPreferenceArray(1);
newIPref.set(0, p);
}
if(existingPosition == -1){
preferenceForItems.put(itemID, newIPref);
}
}
#Override
public void removePreference(long userID, long itemID) {
// User preferences
if (preferenceFromUsers.containsKey(userID)) {
List<Preference> newPu = new ArrayList<Preference>();
for (Preference p : preferenceFromUsers.get(userID)) {
if(p.getItemID()!=itemID){
newPu.add(p);
}
}
preferenceFromUsers.remove(userID);
preferenceFromUsers.put(userID, new GenericUserPreferenceArray(newPu));
}
if(preferenceFromUsers.get(userID).length()==0){
preferenceFromUsers.remove(userID);
userIDs.remove(userID);
}
if (preferenceForItems.containsKey(itemID)) {
List<Preference> newPi = new ArrayList<Preference>();
for (Preference p : preferenceForItems.get(itemID)) {
if(p.getUserID() != userID){
newPi.add(p);
}
}
preferenceForItems.remove(itemID);
preferenceForItems.put(itemID, new GenericItemPreferenceArray(newPi));
}
if(preferenceForItems.get(itemID).length()==0){
//Not sure if this is needed, but it works without removing the item
//preferenceForItems.remove(itemID);
//itemIDs.remove(itemID);
}
}
If by "new distributor" you mean that you have no data for them, no historical data. Then you cannot make recommendations using Mahout's recommenders.
You can suggest other items once they chose one. Use Mahout's "itemsimilarity" driver to calculate similar items for everything in your catalog. Then if they choose something you can suggest similar items.
The items that come from the itemsimilarity driver can be stored in you DB as a column value containing ids for similar items for every item. Then you can index the column with a search engine and use the user's first order as the query. This will return realtime personalized recommendations and is the most up-to-date method suggested by the Mahout people.
See a description of how to do this in this book by Ted Dunning, one of the leading Mahout Data Scientists. http://www.mapr.com/practical-machine-learning

how to store data into temporary instead of database

i want to insert my data into temporary in mvc
I dont want to store data directly into database
For an example, as u visit to a mall and buy 5-6 things, so first it wont store all data in database, instead it stores into somewhere in application.
Like this what logic may i use to make this type of site
public ActionResult Education_Detail(Education objEducation)
{
sp.Reg_Can_Education(ref objEducation);
objEducation.CorColl = (CourseCollection)TempData["objCourseColl"];
TempData["objCourseColl"] = objEducation.CorColl;
for (int item = 0; item < objEducation.CorColl.Count; item++)
{
if (objEducation.CorColl.Item(item).CourseId.ToString() == objEducation.objCourse.CourseId)
{
objEducation.objCourse.CourseNm = objEducation.CorColl.Item(item).CourseNm.ToString();
}
if (objEducation.objCourse.CourseNm != null)
{
break;
}
}
Thank you
Store your data in cookie or session and when user check out store it to database.

Is there an equivalent of Rails ActiveRecord::Callbacks in ASP MVC?

Is there an equivalent of Rails ActiveRecord::Callbacks in ASP MVC?
http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
I'm in a situation where we are not using identities for our primary key. We do this for reasons specific to our DB sharding design. Because of this we have a lookup table to find the next ID for a specific table. I'd like to automatically get this value and set it in an abstract class whenever a model is created/updated and before it is saved. I also need to update the lookup table with an incremented 'nextID' after the save is successful.
I'm open to other solutions on how to do this without callbacks as well.
So you need the callback just to increment ID in the lookup table? AFAIK there is no equivalent in ASP.NET, may be you could try with Async Controllers (http://msdn.microsoft.com/en-us/library/ee728598%28v=vs.100%29.aspx) and wait for a state change from the successful save, but I would prefer use a service specifically for this like Snowflake (https://github.com/twitter/snowflake/).
I found a solution using overrides as opposed to callbacks. It's my hope that ASP mvc adds support for callbacks as the framework continues to mature because callbacks allow for cleaner code by allowing the OnSave event to exist in the model[s] that the event is concerned with rather than the centralized DbContext class (separation of concerns).
Solution:
The SaveChanges method can be overridden in the Context Class (Entity Framework Power Tools creates the Context class is the 'Models' directory).
public override int SaveChanges()
{
// create a cache for id values in case their are multiple added entries in the dbcontext for the same entitytype
Dictionary<string, UniqueID> idCache = new Dictionary<string, UniqueID>();
IEnumerable<DbEntityEntry> changes = this.ChangeTracker.Entries();
foreach (var entry in changes)
{
//check if this is a new row (do nothing if its only a row update because there is no id change)
if (entry.State == System.Data.EntityState.Added)
{
//determine the table name and ID field (by convention)
string tableName = entry.Entity.GetType().Name;
string idField = entry.Entity.GetType().Name + "ID";
UniqueID id = null;
//if we've already looked this up, then use the cache
if (idCache.ContainsKey(tableName))
{
id = idCache[tableName];
}
//if we havn't looked this up before get it and add it to the cache
else
{
id = this.UniqueIDs.Find(tableName, idField);
//if it doesn't already exist in the lookup table create a new row
if (id == null)
{
id = new UniqueID(tableName, idField, 1);
// since this is a new entry add it
this.UniqueIDs.Add(id);
}
else
{
// set the state to modified
this.Entry(id).State = System.Data.EntityState.Modified;
}
}
entry.CurrentValues[tableName + "ID"] = id.NextID;
id.NextID = id.NextID + 1;
}
}
return base.SaveChanges();
}

How to Check the duplicate in application state in mvc asp.net

how to check the duplicate in Application state
My problem scenario:
I stored the username and password in the application[""] variable.
another user enters the username password i want to check for each and every user.
i tried for for loop but hard to find the count..
could you help me check the duplicate
for (int j = 0; j < (int)System.Web.HttpContext.Current.Application["Userlogin"].ToString().Length - 1; j++)
{
if (System.Web.HttpContext.Current.Application[i].ToString() == sKey)
{
Session["duplicateuser"] = "logout";
Returnmsg = "-3";
}
}
but it shows the string length of the application[]
Thank in Advance
I stored the username and password in the application[""] variable
Wow, don't. The Application state is shared among all users of your application. Never store user specific data in application state. Use Session state instead.
UPDATE:
If you want to check for concurrent user access you could store a collection of users into the application state such as IEnumerable<string>. Then you could check if a user is already logged in easily:
public bool IsUserLoggedIn(string username, HttpApplicationStateBase application)
{
var users = application["users"] as IEnumerable<string>;
if (users == null)
{
users = new ConcurrentBag<string>();
application["users"] = users;
}
return users.Any(u => u == username);
}

Null value lingers in cache after Cache.Remove(key)

I added a caching layer between my ASP.NET MVC application and database using the GetOrStore<T> cache helper below.
This includes caching users' system roles.
When I remove a cached roles object for a signed-in user via HttpRuntime.Cache.Remove(userRoleCacheKey), subsequent requests fail with a NullReferenceException because the cache helper is returning a null value for the role cache, even though the cached key should not exist and the helper should regenerate it.
It seems like the cached key lingers around with a null value. The exception won't budge until I request a role-heavy page a few seconds later.
Why is my cache breaking?
public static class CacheExtensions
{
public static T GetOrStore<T>(this Cache cache, string key, Func<T> generator)
{
var result = cache.Get(key);
if (result == null)
{
result = generator();
if (result != null) // can't store null values in cache.
{
cache[key] = result;
}
}
return (T)result;
}
}
Here is the code that fetches the user's roles and caches it:
public override string[] GetRolesForUser(string userId)
{
return HttpRuntime.Cache.GetOrStore<string[]>(
"RolesForUser[" + userId + "]",
() => Con.Query<string>("SELECT Role FROM vw_UserRoles WHERE UserId = #userId", new { userId = Guid.Parse(userId) }).ToArray());
}
where Con retrieves an open IDbConnection.
Minor issue in your code that can hide the problem from you:
if (result != null) // can't store null values in cache.
{
cache[key] = result;
}
What about else clause? The result returned anyway, even if it is null value. Throw InvalidOperationException in that case and debug your queries passed as generator parameter.

Resources