Yesterday i was working on my asp.net mvc application where i was trying to cache some data in a field while a certain controller was in scope. The field kept clearing every time a new view got opened.
Question:
Is it possible to keep your Controller in scope while you're browsing Views that are handled by said Controller?
private static List<string> _listOfStrings;
[Authorize]
public ActionResult ToView1()
{
_listOfStrings = new List<String>(){"test","test2"};
var model = new Model();
return View(model);
}
[Authorize]
public ActionResult FromView1ToView2()
{
var model = new Model(_listOfStrings);
//the issue at hand is that '_listOfStrings' is not persisted.
return View(model);
}
Anyone got an idea if this is possible? (The list is big, so i would prefer not sending it through the model into the view and vice versa)
You need to read about an ASP.NET MVC lifecycle.
Short answer: no, you can't cause Controller is destroyed after a call of an action. Detail answer: you can store (cache) data in a TempData or in a Session properties.
_listOfStrings is a different variable to listOfStrings. You are not writing to or reading from the static field. In the code you have presented, _listOfStrings is not even defined.
Use one static variable and this code will work.
Related
My current situation is as follows.
I have a form that when it gets submitted, passes the model into the controller and it does what it needs to do. At the end it redirects to a confirmation page that also gets passed the same model. All of that works fine, except when I am on the confirmation page, whenever I reload the page it resubmits the form.
I've tried using TempData but when I use that it requires for my model to be serializable and my model uses other models inside it that were made by other people that all need to be serializable which would result in like 15-20 different classes all needing to become serializable which just doesnt seem reasonable.
Here is some of what I am working with:
[HttpPost]
public async Task<ActionResult> SubmitClaim(WarrantyClaim model)
{
... code ...
return BeddingWarrantyConfirmation(model);
}
public ActionResult BeddingWarrantyConfirmation(WarrantyClaim model)
{
return View("BeddingWarrantyConfirmation",model);
}
You could make use of the Post Redirect Get Pattern. You could return the following in SubmitClaim:
return RedirectToAction("BeddingWarrantyConfirmation", "CONTROLLER", model);
For more information, please see https://en.wikipedia.org/wiki/Post/Redirect/Get
This is a common problem in MVC development, you can follow the Post/Redirect/Get strategy to avoid the request.
https://en.wikipedia.org/wiki/Post/Redirect/Get
Hi I cant find the way to pass data between Action methods within one controller. The simplified code example is as follows:
public class HomeController : Controller
{
int latestID;
// GET: Home
public ActionResult Index()
{
latestID = 50000;
return View();
}
// GET: Generate
public ActionResult Generate()
{
// using the latestID here
return View();
}
}
Index loads when the app starts and latestID is set to 50000. But when I click button mapped to API GET request Generate, the latestID is suddenly null. I tried to implement TempData and Session but with no luck. Any help would be greatly appreciated!
I feel there are 2 possibilities here i.e. the value to be retrieved is for a user session or its global across all the users using the website.
If the value is user specific then it can be managed through session stage management like Viewbag. Or if this value is expected to be maintained on the server side alone then it needs to be retrieved again through some persistence mechanism like database or memory cache.
If the value is common across all the users using the Website then it can be achieved through the Dependency Injection of a singleton object (this can be a database manager or cache manager again or a simple in memory object). The static objects can be used as well but it wouldn't be ideal as the application wouldn't support horizontal scalability across instances.
I found that I shouldn't use Session a lot in ASP MVC here, here and in other places.
So, I want to know if it's better to use TempData like I did below or not.
public ActionResult Action1()
{
if (SomeCondition)
{
/*
I want to show alert to user based on this value that should appear in Action2 view
So, is it better to:
1. Session["user"] = "something";
2. TempData["user"] = "something";
*/
return RedirectToAction("Action2");
}
return View();
}
public ActionResult Action2()
{
/*
1. I can read Session["user"] in the view
2. TempData["user"] = TempData["user"].ToString();
Now I can read TempData in the view
*/
return View();
}
TempData is a provider that uses Session by default. It can be changed to be a cookie-based provider, though.
The only real difference is that TempData stores the data only until it is read again, where Session will store the data until a timeout expires.
There is no perfect solution for storing data between requests. When possible, you should avoid it. In MVC you can do this fairly easily by loading the data into the View and posting the ViewModel back to the controller where you can read the data again.
Also, see Think twice about using session state for some possible alternatives to session state.
I am using ASP.NET and MVC 3 in visual studio and have a question about passing an object from one action method(called Search) to another(called SearchResult). I tried using ViewData but it didnt persist down to the View of SearchResult. Below is a snippet of my code, from within a single controller. 'Search' gets called when data has been collected from a form and submit has been called(hence the [HttpPost] declaration):
[HttpPost]
public ActionResult Search(Search_q Q){
// do some work here, come up with an object of type 'Search_a'
// called 'search_answer'.
ViewData["search_answer"] = search_answer;
return RedirectToAction("SearchResults");
}
public ActionResult SearchResult(Search_a answer)
{
return View(answer);
}
I also tried using RedirectToAction("SearchResults", new {answer = search_answer}); instead of the above call to RedirectToAction but my 'search_answer' still didnt persist to the View. What is the best way to send this Search_a object to the SearchResult View?
You can use TempData to pass the object.
[HttpPost]
public ActionResult Search(Search_q Q){
// do some work here, come up with an object of type 'Search_a'
// called 'search_answer'.
TempData["search_answer"] = search_answer;
return RedirectToAction("SearchResult");
}
public ActionResult SearchResult()
{
var answer = (Search_a)TempData["search_answer"];
return View(answer);
}
If TempData does not suffice (what Eranga suggested), because SearchResult is not somewhat dependent on a Redirect (though you can have checks to get around it), you might want to look at the Request object. You can likely store the data as one of the query parameters via Request.Params. This can take advantage of the ModelBinding filter chain that Asp MVC has.
Hi,
I have a action that looks like this :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(AdRegister adRegister, IEnumerable<HttpPostedFileBase> files)
The AdRegister is a complex class and I need to pass this in to a redirect method further down in the Register action, like this :
return this.RedirectToAction("Validate", adRegister);
The Validate action looks like this :
public ActionResult Validate(AdRegister adRegister)
I do know that I can pass simple parameters but in this case itĀ“s a complex object. This example do not work, the adRegisterĀ“s properties will be null.
Is this posible and if so, how?
BestRegards
More Information : Register action will take the adRegister and do som magic on it, then It will be sent to the Validate action. The Validate action will return a validation page to the user. When the user hit the grant button the adRgister will be filled from the form and then sent to the vValidate post where it will be saved. I have looked in to place the adRegister in cache or database temporarily but it will be better if I could simple pass it to the next action.
One possibility would be to pass the simple properties in the query string:
return RedirectToAction(
"Validate",
new {
foo = adRegister.Foo,
bar = adRegister.Bar,
... and so on for all the properties you want to send
}
);
Another possibility is to store it in TempData (for the lifetime of the redirect) or Session (for the lifetime of the ASP.NET session):
TempData["adRegister"] = adRegister;
return RedirectToAction("Validate");
and then retrieve it from TempData:
public ActionResult Validate()
{
adRegister = TempData["adRegister"] as AdRegister;
...
}
Yet another possibility (and the one I would recommend you) is to persist this object in the POST method in your datastore:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(AdRegister adRegister, IEnumerable<HttpPostedFileBase> files)
{
...
string id = Repository.Save(adRegister);
return RedirectToAction("Validate", new { id = adRegister.Id });
}
and then fetch it from the data store after you redirect:
public ActionResult Validate(string id)
{
AdRegister adRegister = Repository.Get(id);
...
}
an idea would probably create a session variable and pass around a Key that references that session variable if the object is required acorss a few views?
ASP.NET MVC's tempdata should be perfect for this.
That said, TempData or Session is one option, but has some downsides like being quite violate and oftentimes murky or difficult to debug. What might be preferable is to "stash" the temporary value in a persistent store, such as the user's profile or your own database, then pass a key through the validate method which can then load the data from said store. This also opens up the possibility of recovering abandoned carts and such.