I am learning ASP.net MVC5 with the code in book.
public ActionResult DemoTempData()
{
ViewData["Msg1"] = "From ViewData Message.";
ViewBag.Msg2 = "From ViewBag Message.";
TempData["Msg3"] = "From TempData Message.";
return RedirectToAction("Redirect1");
}
public ActionResult Redirect1()
{
TempData["Msg4"] = TempData["Msg3"];
return RedirectToAction("GetRedirectData");
}
public ActionResult GetRedirectData()
{
return View();
}
GetRedirectData view:
#{
ViewBag.Title = "GetRedirectData";
}
<h2>GetRedirectData</h2>
<ul>
<li>ViewData-Msg1:#ViewData["Msg1"]</li>
<li>ViewBag-Msg2:#ViewBag.Msg2</li>
<li>TempData-Msg3:#TempData["Msg3"]</li>
<li>TempData-Msg4:#TempData["Msg4"]</li>
</ul>
I know that ViewData and ViewBag will not pass value.
The Msg3 and Msg4 in view should have value, but it doesn't.
I check the value in Redirect1(), it turns out that Msg3 is null.
I am very confused with what's going on.
ASP.NET MVC TempData stores it’s content in Session state. So TempData gets destroyed immediately after it’s used in subsequent HTTP request.
In your case you are assigning the TempData["Msg3"] to TempData["Msg4"]. So once you consume the content from TempData["Msg3"] it gets destroyed. So whenever you try to access TempData["Msg3"] you get null value.
The Peek and Keep methods allow you to read the value without getting destroyed.
reference :
https://msdn.microsoft.com/enus/library/system.web.mvc.tempdatadictionary.peek(v=vs.118).aspx
object value = TempData["value"];
TempData.Keep("value");
object value = TempData["value"];
in the controller Use the builtin Session plumbing, it stays with you until you destroy it. I like it because it always works, and its easy. It is available in
System.Web.HttpContext
which is really the current request
to save use (Example)
System.Web.HttpContext.Current.Session["Msg3"] = StringOfIds;
To retrieve...
string msg3= (string) System.Web.HttpContext.Current.Session["Msg3"];
Related
Basically I am learning about difference between ViewBag, ViewData, TempData in practical.I am in confusion with the theory of these concepts so I want to see how things happen in practical.
I learned that TempData is used to send data from controller to controller i.e from one action method to another action method, and it is short lived.Even then I can pass TempData value to a View as well. As I read that it's value gets null after subsequent request. But In my sample code snippet though there exist a value in TempData after a redirection, I'm unable to assign it to a variable.
public ActionResult Index()
{
var featuredProduct = new Product
{
Name = "Special cupcakes",
Des = "Delectable vanilla and chocolate cupcakes",
Creationdate= DateTime.Now,
Expirydate= DateTime.Today.AddDays(7)
};
ViewData["FeaturedProduct"] = featuredProduct;
ViewBag.product = featuredProduct;
TempData["FeaturedProduct"] = featuredProduct;
return Redirect("~/Home/Show");
}
As this is the first redirection i.e next subsequent request after setting TempData, the value should persist in TempData of Show Action method.
public ActionResult Show()
{
var testdata= ViewData["FeaturedProduct"];
var testbag = ViewBag.product;
var tempdata = TempData["FeaturedProduct"];
return View();
}
Now my confusion is around here. If I want to access TempData in the Show View, I expect that it should be null. When I see in Quick Watch,it's value persisted and it's value is not getting assigned to the variable.So What exactly is happening with TempData.
#{
var tevar = TempData["Featured Product"] as Product;
}
#{
if (TempData["Featured Product"]!=null)
{
<b><u>
#tevar.Name
</u></b>
}
else{
<b> Sorry tempdata values perished</b>
}
}
Though this appear very basic please bear with me and explain me what happening with TempData in my code.
Thank You.
You've got a typo in your Show view:
#{
var tevar = TempData["Featured Product"] as Product;
}
should of course be:
#{
var tevar = TempData["FeaturedProduct"] as Product;
}
Make sure that you access the value using the same key as you stored it with.
I could now clearly comprehend the difference between ViewBag, ViewData, TempData.
ViewBag and ViewData value will be lost after redirection, but TempData value will remain between the redirection until a refresh of the current action method occurs or if we navigate to other action method.
I use MVC 4 and have moved some logic into an authorize filter. I am trying redirect to an error page based on not being authorized. I would like to set the last page route and a few other properties to catch the error.
Below is my override
// handle unauthorized
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Controller.ViewBag.LastRoute = filterContext.RouteData;
filterContext.Controller.ViewBag.Issue = "put...val here";
var routeValues = new RouteValueDictionary(new
{
controller = "Error",
action = "Oops"
});
filterContext.Result = new RedirectToRouteResult(routeValues);
}
controller
[AllowAnonymous]
public ActionResult Oops()
{
var m = new Core.Models.ErrorModel();
var v = ViewBag.Issue; // == null
return View("~/Views/Error/Oops.cshtml", m);
}
I tried how to set values to viewbag in actionfilterattribute asp mvc 5 for action filters and it works
Any help would be appreciated.
EDIT:
Sorry when I get to the controller the value for:
ViewBag.Issue = null.
I'm not sure how to set the property and have it hold value.
RedirectToRouteResult is going to send a redirect response to the browser and browser will issue a brand new GET request to the url specified. ViewBag data do not survive between 2 http requests.
You may use TempData which will keep the data between 2 seperate http requests. You can set your TempData value in one action method and any action method that is called after this can get values from the TempData object and then use it. TempData use Session behind the scene to store data. The value of TempData persists until it is read or until the session times out. This is ideal for scenarios such as redirection because the values in TempData are available beyond a single request.
So in your action filter you can set the TempData dictionary instead of ViewBag.
filterContext.Controller.TempData["Issue"] = "Robots are laughing non stop";
var routeValues = new RouteValueDictionary(new
{
controller = "Home",
action = "Oops"
});
filterContext.Result = new RedirectToRouteResult(routeValues);
Now in your Oops action method, you may read the TempData value you set
public ActionResult Oops()
{
var issueDetails = TempData["Issue"];
// TO DO : Do something useful with issueDetails :)
return View();
}
Keep in mind that TempData values won't be available after you read it. So if you want to read it in your view again, set it again or better use a view model and set the already read value as the property value of your view model.
How to add a query string from surface controller in umbraco mvc . This is my current code.
Initially I wrote a code like
public ActionResult Registration(RegisterModel model)
{
//Code to insert register details
ViewBag.Success="Registered Successfully"
return CurrentUmbracoPage();
}
with this I could successful persist my ViewBag and model properties value but I could not add a query string with it.
For certain requirement I have to change the code that returns a url with querystring.
which I did as below
public ActionResult Registration(RegisterModel model)
{
//Code to insert register details
ViewBag.Success="Registered Successfully"
pageToRedirect = AppendQueryString("success");
return new RedirectResult(pageToRedirect);
}
public string AppendQueryString(string queryparam)
{
var pageToRedirect = new DynamicNode(Node.getCurrentNodeId()).Url;
pageToRedirect += "?reg=" + queryparam;
return pageToRedirect;
}
and with this my values of the properties in model could not persist and the ViewBag returned with null value.
Can any one suggest me how to add query string by persisting the values in the model and ViewBag.
Data in ViewBag will not be available on the View when it redirects. Hence you have to add message in TempData which will be available in the View after the redirect like TempData.Add("CustomMessage", "message");
I am calling a controller from more than one page and am using a returnUrl parameter to return the correct calling location:
public ActionResult EmailOrder(int id, string returnUrl)
{
var message = "The order has been emailed";
if (!string.IsNullOrEmpty(returnUrl)) return Redirect(returnUrl);
return RedirectToAction("Details", new { id, message });
}
How can I pass additional information back to the view when using Redirect(url)? In the above example, I want to be able to pass message back when returnUrl has a value.
If you are redirecting to another action method and you want to pass data that can be access in the new action method, you should use the ASP.MVC Controller TempData property. You use this as follows:
[HttpPost]
public ActionResult MyActionMethod(Order order)
{
// write your logic here to save the Order
TempData["message"] = "here is some message";
return RedirectToAction("Index");
}
Data in the TempData member will be preserved across a redirection. It will be accessible in the redirected page, and then will be removed. Once you read an entry in TempData, it will be marked for deletion.
public ActionResult RedirectedMethod()
{
//Retrieve data from TempData. It will then be marked for deletion
var data = TempData["message"].ToString();
}
If you want to get a value without marking it for deletion, you can use the "Peek" method:
var data = TempData.Peek("message")
Also, you can manually preserve a value that would otherwise be deleted by using the "Keep" method:
TempData.Keep("message")
TempData is of type TempDataDictionary.
Note that TempData uses ASP.Net Session state behind the scenes, so you must have session state turned on if you are using TempData.
For more information on TempData, see here.
I am trying to use session state in MVC and I have been stuck for the entire evening!
I realise session state should be used sparingly in MVC - but I am sure I want to use it for this one page - so would appreciate solutions rather than opinions.
Basically, I have a contact form with a CAPTCHA image. When the page loads I want to set the session to the characters used in the CAPTCH image (dynamically generated image).
I have an 'new image' link which async creates a new code, sets the session and dynamically loads a new image to screen.
The session stays sets as long as the page doesn't load or reload. I need to be able to validate the user input against the code in session (which should reflect what is displayed to the user) but the session is empty.
If I perform an AJAX reload on the image i.e. set the session asynchronously - the session is set when I perform a post!!
What's going on?
I need to be able to persist the session value - arrrhhhh!
I have this is a base controller:
public new HttpContextBase HttpContext
{
get
{
HttpContextWrapper context = new HttpContextWrapper(System.Web.HttpContext.Current);
return (HttpContextBase)context;
}
}
and in the controller I have:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Contact(ContactForm c, string button)
{
string sessCaptcha = HttpContext.Session["CAPTCHA_Contact"] == null ? "" : HttpContext.Session["CAPTCHA_Contact"].ToString();
}
Any ideas????? pretty pls with a cherry on top :)
Thanks!
I am so embarrased right now...
Never ever set a session value before a Response.End() (and i believe also the same applies to response.redirect).
OMG - that's 4 hours I will never ever get back again!
Here is the demo code to illustrate my ineptitude...
public ActionResult Page1()
{
Session["test1"] = "hello world";
// This means the session won't be set
// It's is used in valid circumstances..e.g. setting session, then dynamically generating an image based on that value.
Response.End();
return View();
}
public ActionResult Page2()
{
ViewBag.Test = Session["test1"].ToString();
return View();
}
[HttpPost]
public ActionResult Page2(FormCollection fc)
{
ViewBag.Test = "...is still..." + Session["test1"].ToString();
return View();
}
You may want to look into using the TempData object
http://blog.donnfelker.com/2010/02/26/aspnet-mvc2-tempdata-now-persists/