Session value is always null - c#

This is an ASP.NET MVC project. I'm trying to retrieve value from a session and it always returns null.
The SaveToSession & GetFromSession methods are in a separate helper class.
When the submit button is clicked, it makes a call to the controller method and in turn to the helper method to save data in session.
Another anchor tag click (which has the controller path) will hit the same controller which calls the helper method to fetch the data from session. This is where the data is null always.
These are the methods in my helper class
public static void SaveDataInSession(string sessionName, IEnumerable<Item> lstData)
{
System.Web.HttpContext.Current.Session[sessionName] = lstData;
}
public static void GetDataFromSession(string sessionName, out IEnumerable<Item> lstData)
{
lstData = null;
var test = System.Web.HttpContext.Current.Session; //This session has a new SessionID and hence does not have the data.
if (System.Web.HttpContext.Current.Session[sessionName] != null)
{
// it never comes into this block
}
}
During debug, I can see that the data is saved into the session as I can see the session name in the keys list.
The same code worked fine in another ASP.NET MVC project. I checked the web.config file of that project if there were any session related entries and there were none.
UPDATE: I have observed that, when saving the data the session id generated is different and when fetching the data, it has another id. I think this could be the reason, but why is it creating new session Ids when I'm not even refreshing the page. What can be done to fix this.
The System.Web.Mvc version is 5.2.3.0

Related

Data is added in front end every time the page is refreshed?

I have an application in ASP.NET MVC with a simple form which reads data from a file and shows the data in the form in browser.The issue is that every time I refresh the browser,the data from the file is added again in the front end.This is the controller where I have the issue:
public ActionResult Main(BankingModel _bm)
{
ViewBag.List = IO.Read();
return View(_bm);
}
IO.Read reads the data from the file,stores it in the Viewbag and send it to the view.But the controller is called every time I refresh the page and the data from the browser remains,resulting in duplicated values.Is there a way,when I refresh thee browser,to also refresh the front end view data from the form?
Regarding your particular case, you were not intiailzing a new instance of your List<BankingModel> which caused the data to be appended to the list always. The solution to this would be to initialize a new instance of your list inside the Read method:
public static List<BankingModel> lst = new List<BankingModel>()
And in order to clear your ViewBag since ViewBag maintains data on refresh, you can just call ViewData.Clear(); in your Controller method since ViewBag uses it internally.

Session is passing like a primitive type?

I have a MVC Core Dotnet application and basically I wanted to load a view of session data but also remove the session after the page loads. My code works but I don't understand why
public IActionResult Charge(string stripeEmail, string stripeToken, int totalPrice){
//some stripe code that went here...
var cart = HttpContext.Session.GetCart();
ClearSession();
return View(cart);
}
protected void ClearSession(){
//creates a new instance if cart doesnt exist otherwise returns it
var cart = HttpContext.Session.GetCart();
//clears the items from the collection using .Clear() ...
cart.RemoveAll();
HttpContext.Session.SetCart(cart);
}
the code works when its placed in a new method like so.. but if I placed it in the same method it doesn't work. I am surprised by placing it in a new method it worked as it goes against my understand of how pass by value works with object types.. (the location of the object will be passed). Its acting like a copy of the object was made when I cleared the Item list in the new method.
Why does this code work?

Get Page control in a Method triggered by AJAX call

I call a method in a separate Class file that needs to update a label.
[WebMethod] //needed for the AJAX call
public static void MyClick(int postid, int userid) //must be static
{
Page page = new Page();
//Page page = HttpContext.Current.Handler as Page //Pass the Page but don't work
MyClass.MyMethod(postid, userid, page);
}
The method MyClick() is called from an asp.aspx file (With MasterPage), to a separate MyClass.cs file.
I am not being able to get the Control (Label) with FindControl(). My guess is the "Page" is not being passed correctly. For what i've seen in debug, "page" comes with many exceptions.
((Label)page.FindControl("ContentPlaceHolder1_lbl)).Text = "foo";
This is the sequence:
1) User clicks sort of a "Like" dynamically-created LinkButton
2) There is a JS listener that on click changes to "Dislike" (example) and does an AJAX POST to aspx page method MyClick() with parameters (postid, userid).
3) MyClick() calls MyMethod(postid, userid) that is in MyClass.cs
4) MyMethod() does some SQL (was working) and updates the label (AJAX call not working since MyMethod() tries to set label to "foo").
You're not passing the current page, you're creating a new one:
Page page = new Page();
You could just pass a reference to the current page:
MyClass.MyMethod(postid, userid, this);
(Though in order to do that your page method shouldn't be static. In fact, in order to reference anything on the page instance that method shouldn't be static. See edit below)
However, in general it's best practice not to have other components rely on your page elements. Only the page's code should know/care about the UI elements it owns.
Instead of having the method set the value, have the method compute and return the value and then have the page set it. Something like this:
var result = MyClass.MyMethod(postid, userid);
myLabel.Text = result;
That way the external component isn't tightly coupled to this specific page, can be re-used by other pages, etc.
Edit: What you're trying to do physically won't work in the framework you're using. AJAX-invoked web methods are static for a reason. They don't maintain page state. So in the context of that web method there is no page and there is no label. The AJAX call is a simple service which accepts values and returns a response.
So even if you could update a label server-side, that's not going to do anything client-side. Your client-side code needs to update the markup in the browser. To do that, the AJAX call should simply respond with the new value and the JavaScript code should use that returned value to update the page. Something like this:
[WebMethod]
public static string MyClick(int postid, int userid)
{
return MyClass.MyMethod(postid, userid);
}
As in the earlier part of this answer, that external component should simply calculate and respond with the new value. It should not be coupled to the page. This web method should result in the client-side code receiving the updated value. Then, however you manage that client-side (you have no client-side code in the question), you would update the page markup with that resulting value.

Is it acceptable to store user specific data in C# Runtime MemoryCache?

In my asp.net MVC app, each page contains a lot of data that changes very rarely, but is still user specific and should never be shared among other users.
I couldn't find a server side solution that handled a cache per-user, so my idea is to just use the 'standard' memorycache and use the user-ID as part of the key.
Is this acceptable? Am I missing some security risks?
Thanks
EDIT: (added details)
It is data that is originally stored in the database, for example, I have a custom-made dropdown list (which is retrieved using AJAX and returns a jsonresult) for product-categories. I want to be able to manually clear the cache, in case the user adds a category via settings and I need the retrieve a 'new' category list. To my knowledge I cannot manually clear the cache with OutputCache. I also have a scenario where I want to refresh certain cache item every minute (for some updates on the user's screen).
Annotate your action with OutputCache and for consistency make sure the action is for authorized access only.
[Authorized, OutputCache(VaryByCustom = "USER")]
public ActionResult SlowAction() { }
Then in Global.asax.cs override the 'VaryByCustom' handler
public override string GetVaryByCustomString(HttpContext context, string custom)
{
switch (custom)
{
case "USER":
return context.User.Identity.Name;
default:
return null;
}
}

Losing session data stored in one PartialViewResult when trying to retrieve it in another PartialViewResult

I have a scenario where in I am using the Session to store an object in one controller action and trying to retrieve it another controller action. Both the actions are triggered from the same view and reside on the same controller. Unfortunately, I am not able to retrieve the session variable in the second controller. The session Id remains the same and I am ensuring that the object was written into the session in the first action. The session data, however, disappears when the view is returned in the first action.
Here is my Controller code flow -
public PartialviewResult DoSearch(string paramCustId)
{
//invoking a method to perform a search task. I am also passing the controller session as a parameter
//this function is called in a separate thread and the main thread does not wait for it to complete before returning the view
multiSearch(paramCustId, Session);
}
return PartialView("_partialView1");
public void multiSearch(string searchParam, HttpSessionStateBase controllerSession)
{
//code to retrieve response from backend into the variable tempSearchSet
controllerSession["searchResult"] = tempSearchSet;
//verified that tempSearchSet is stored in Session under the key "searchResult" and Session.Count is 1.
}
//Another controller action that is triggered from the same view after a certain delay to fetch the data in session
public PartialViewResult PollSearchResults()
{
var tempSearchResult = Session["searchResult"] as List<SearchResultSet>;
//This is where i do not see data in the session. I have verified that the multiSearch method is complete and has updated the data in the session.
//here Session.SessionID is the same as above, but Session.Count is 0
}
Is there a different way to handle Session in mvc or am i missing something elementary here? Also, is there a better approach to manage this caching scenario?
Found the solution. I had to initialize the session variable in the Session_Start method of Global.asax.cs. This one line made it work for me.
HttpContext.Current.Session.Add("searchResult", new List<SearchResultSet>());
I am still unclear why this line is needed as the session variable get and set worked in the first action method without the initialization. Guess i'll keep that for future research.

Categories