Keeping data in model safe - c#

Suppose I were to have a web application and a view called innerPage for the application who's model looks something like this:
public class innerPageModel
{
public bool isFirstTime = true;
public List<int> threadIDList;
}
And here is the controller for my innerPage:
public ActionResult innerPage(InnerPageModel model)
{
if (model.isFirstTime == true)
{
Thread t = new Thread(Work);
model.threadIDList.Add(t.ManagedThreadID);
model.isFirstTime = false);
}
System.Diagnostics.Debug.Write((model.threadIDList.Count).toString());
}
Now my innerPage view is being refreshed every 5 seconds and therefore traversing my innerPage controller each time. The problem is that all of the data in my model is being reset after every time I traverse the controller (Everytime it goes inside the if-block, indicating that model.isFirstTime is being reset to true when I only want to traverse that if-block on the first time). Likewise, my model.threadIDList is being reset everytime through.
Is there a way for me to save the data in my model such that it isn't lost everytime my view refreshes?

The MVC model assumes the controller will be invoked, return an ActionResult and then be done.
It does not seem safe to kick off threads in the controller action.
If you need data to remain between HTTP requests, you can store it in the Session or in Cache, depending on whether the data is per-user or global to the website.
If you need true background processing, look at
WebBackgrounder
Quartz.NET
FluentScheduler

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 value is always null

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

ASP.NET MVC form wizard prevent user skipping wizard step (Controller Action) using URL bar

I’m currently working on a very large form. I thought it would be a good idea to section the form by implementing a form wizard (multiple views/action results) to improve the user experience.
One requirement is that the user must complete a small eligibility test that ensures they meet the minimum requirements prior to starting the application wizard itself.
Having done nothing like this before I can only see one approach to this problem and that is using a flag e.g IsEligible in a session that determines if the user can access the form wizard view/s. Let’s say my controller has two ActionResults (Eligibility and WizardStepOne) that server separate views. For example:
Controller - Untested Code
public ActionResult Eligibility()
{
Return View();
}
[HttpPost]
public ActionResult Eligibility(EligibilityViewModel model)
{
if(!ModelState.IsValid)
{
return View(model);
}
Session["IsEligible"] = true;
return("Success");
}
public ActionResult WizardStepOne()
{
bool stuff = (bool)Session["stuff"];
if(IsEligible == null)
{
return("Eligibility");
}
return RedirectToAction("Eligibility");
}
In short if the user attempts access the first step of the wizard and the IsEligible flag hasn't been set by the Eligibility post action then the user get redirected back to the eligibility form.
I've also looked into action filters but couldn't make much sense of it. I'll also have to implement this functionality at a later stage to prevent users skipping between wizard steps using the url e.g skipping WizardStepOne and starting at WizardStepTwo.
Is there a better approach then one described above in this situation? I'd rather avoid using a session as restarting the form becomes problematic as it would require a restart button to abandon the session especially between wizard steps.
What you are mentioning sounds like you might make use of some simple state machine to define valid steps through your form. So, when user is at stage 3. for example, you will check if he came from step 2 or not. For each step for particular user and session > you can save some hash value in his session. That way they could make no use typing in url directly.

Will an MVC model used as a field in a controller be overwritten on each request?

Have a currious situation where a colleague wrote some code, and now when multiple people access the page she constructed, the site will overwrite User A's model data with User B's model data, if user B comes in and starts a census after User A.
Is it the fault of the model being used as a field in the controller? She originally had it static, which horrified me, so she changed it to non static field, but something still seems off to me.
namespace App.Controllers
{
public class HomeController : Controller
{
private Census _census = new Census();
public ActionResult UploadCensus()
{
return View(_census);
}
[HttpPost]
public ActionResult UploadCensus()
{
if (ModelState.IsValid)
{
// Save Census Model to Database
}
}
}
}
I've never used models this way, because I pass them back and forth from view to view, but wanted to see if anybody had any ideas.
Per Ben Robinson this is the correct answer.
Yes you get a controller instance per request so any instance fields will be specific to that instance and request. Static fields will remain but be shared across app domain so each request will be writing to /reading from the same shared field. So this would account for the overwriting behaviour you have observed.

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