I'm working on rewriting an MVC application that currently utilizes cookies to hold data between multiple pages such as a date. I have tried to come up with an option that would hold the data in the controller by using something like this:
public DateTime HoldDate {get; set;}
The problem that I'm facing is that this is overwritten on each page load. I have also considered using Vue to store the variable and then sending the date to the controller on page load, but I'm not sure how to perform this.
Any help is appreciated and thank you in advance!
You can use TempDataDictionary to pass data from the controller to the view and back. It's a Dictionary, so you can access it with a key:
TempData["HoldDate"] = new DateTime(2020, 2, 13);
When you read data normally from TempData, it is automatically marked for deletion with the next HTTP request. To avoid that, since you want to pass this data around, use the .Peek() method, which lets you read the data but does not mark it for deletion.
var date = TempData.Peek("HoldDate");
If you need data to persist during the entire user session, you can use Session. For example user id or role id.
if(Session["HoldDate"] != null)
{
var holdDate= Session["HoldDate"] as DateTime;
}
If you need data only persist a single request - TempData. Good examples are validation messages, error messages, etc.
if (TempData.ContainsKey("HoldDate"))
{
var holdDate = TempData["HoldDate"] as DateTime;
}
TempData and Session, both required typecasting for getting data and check for null values to avoid run time exception.
Related
I have real time data coming from energy meters and I have to render this data to a table. I am a beginner and do not know how to append data to a Session. When I add data to the Session the old data gets lost.
public void Get_Real_Time_Values(Real_Time_Values values)
{
//please any guidance for appending data
Session["values"] = values;
}
if (datList.Count >= 100)
{
datList.RemoveRange(1, 20);
}
the data in Session is identified with a key. You cannot simply append data to it, but what you can do is append data to it in an indirect manner:
How?
Well, first read the data from the session into an object, list of object whatever you have, then append your new data to it then store the data back in the session.
An example would look like this:
Real_Time_Values currentSessionData = (Real_Time_Values )Session["values"];
currentSessionData.Add(newData)
Session["values"] = currentSessionData;
Be careful with how much data you store in the session though. If you have too much data you might want to start using a database or some sort of caching layer.
Im trying working on a web app project and trying to figure out how to display my answer on the second web page.
I have put a a text box on my first webpage and have corrected the coding of my application as I have received the correct answers in the textbox after I have debugged it.
Ideally I want to remove this textbox and want my answers which I managed to display on my textbox displayed on a label in the next webpage. Here is the calculation part of my code;
var cost = ((int)duration.TotalMinutes) * 0.35m;
txtCost.Text = cost.ToString("c");
I'd like to make my answer appear in my second webpage and not have it displayed in the first. I have tried using Session["Cost"] = cost; on the button click event handler of the first webpage double cost = (double)(Session["Cost"]);
lblDisplay.Text = cost.ToString("c");
and this on the second webpage but every time I Debug it and run I always get $0.00 displayed on my label. Can someone help me fix this?
Sharing value between two views in MVC application, try following
// To save into the Cache
System.Web.HttpContext.Current.Cache["CostKey"] = cost;
// To retrieve Cache Value
var cachedValue = System.Web.HttpContext.Current.Cache["CostKey"] as double;
For Session State, have a look at this link
In ASP.NET WebForms application, you can pass data around in various ways:
Cache
See the Learning Curve answer for examples.
However, the object put in the cache is not guaranteed to be found again if the server experiences memory shortage or alike. The ASP.NET manages the cache and evicts objects on its own to maintain memory availability. This is in contrast with ApplicationState and SessionState where the objects are kept until they are removed manually, or the Application ends or Session expires.
Session and Application states
You can put any object in the SessionState object and retrieve it elsewhere in your code. However, you need to cast it appropriately as the SessionState accepts object-s. E.g. if you store a number, when you retrieving it, you must do the casting yourself, just as you already did it.
The reason it doesn't work, is perhaps you're trying to retrieve it from within another user's SessionState. Yes, the SessionState is a per-user structure. If you need to add the value as from one device and use it on another, use ApplicationState:
Application["cost"] = cost;
Redirecting Response
Using this technique, you could force the browser to request another page from the server and specify the full query string, including the variables you need. E.g. :
var destination = Server.UrlEncode("/someOtherPage.aspx?cost=34.65");
Response.Redirect(destination);
As an alternative, you can use Server.Transfer("someOtherPage.aspx") to save the roundtrip. However, in that case, the browser doesn't change the address in the address bar so the user is misled that she browses one page, but in fact, it is the someOtherPage.aspx.
Session["SelectedRecords"] is used to contain the Id's of selected records, e.g.
SelectedRecords: 1108392 1108393 1108394
When I fire an ajax post that removes an id from the Session["SelectedRecords"] which as far as server side is concerned successfully removes the ID from Session["SelectedRecords"]...
List<int> ids = SessionHelper.GetSelectedRecordIds();
ids.Remove(selectedItemModel.Id);
string csv = string.Join<int>(",", ids);
this.Session["SelectedRecords"] = csv;
using an onSuccess/onRequestEnd event I then use console.log to output the Session["SelectedRecords"] to check.
function onRequestEnd(e) {
console.log('onRequestEnd SelectedRecords: ' + #Session["SelectedRecords"]);
}
But the console.log shows that Session["SelectedRecords"] (as far as the client is concerned still contains the removed id?!)
So the question is when I remove a value from Session["SelectedRecords"] via an ajax post and afterwards access Session["SelectedRecords"] in the view, the view is reporting 'old' values i.e. not the latest values?!
Generally, when you have one object in Session and you POST a delete, you have to remove it also from the Session. This is done like below:
Session.Remove("key");
where key is the unique key you have used to store the item in the Session.
However, in your case this will not work. You have to do two things:
Remove the SelectedRecords from the Session.
Add the new SelectedRecords (without the one record you deleted with your POST) to the Session.
After doing this (which after your update it seems you already have this logic in your code), you have to return back to the client the new SelectedRecords and replace the old value with the new.
Something like this:
$("#selectedRecords").val(newSelectedRecords)
The above should be executed in the success callback of your AJAX call.
Is there a way to pass a parameter to a controller without putting it on the URL?
For example,
http://www.winepassionate.com/p/19/wine-chianti-docg-la-moto
has the value 19 on the URL. If you actually change that value to another, the page displays a different record even it the page name remains the same.
So I would like to NOT pass the ID on the URL but still be able to pass that to the Controller.
What's the recommended way to do so?
You can do a post and send it as a form parameter. I do not recommend this. Posts should be for requests that modify data. In this case you're most likely looking just to get that data. The fact that the id is in the URL is a good thing (see the Stack Overflow URLs for reference). If you really don't want the user to be able to modify it (I hope it's not because you think this makes it more secure, because it doesn't), you could do some simple encryption on it to make it more difficult to guess/produce a valid ID.
Using TempData, as some other suggest, is not a robust solution. It won't work for links on a page, just a GET after POST, and then only once since TempData is deleted after the next request.
Well, you have a couple of options:
Is this a form post? If so, then you can simply add a specific key value pair to your form when you submit it and then data will be passed along.
Is the URL unique to that resource? i.e. Does "Wine-chianti-docg-la-moto" exist as a unique representation of the number 19 in a database somewhere? If so, then you can simply do a lookup of that route component in your database to retrieve the value you need (or push that logic all the way down to the database).
Is that a value that is not expected to change a bunch? You can set that value in Session or in a cookie that would be persisted across pages and then pull it from the respective collection.
Are you redirecting to this page from another request on your server? If so, then you can use TempData to store this temporary value. However, I would recommend against this approach, as it is very transient and not good practice imo.
Lastly, you can obscure the value on the URL if you dont want it to be easily user editable. Encrypt it with some algorithm, and then decrypt it on the destination page. The user will be unlikely to be able to alter the ID by typing in a different value in the URL.
If the page is a GET, and you are following the PRG like you should be (Post-Redirect-Get) then you can use TempData["dataName"] = value; in your [HttpPost] controller and then consume it in your [HttpGet] method. It really depends on how the page is being called.
However, there is nothing wrong in letting the user change that number if it is not security related, and is common practice to show non-vital information in the url like that.
You should use TempData in this case. A good read on this can be found on this blog.
TempData allows you to store a value temporarily between requests and is, by default, erased after being accessed.
// TempData samplepublic ActionResult Featured(){ var featuredProduct = new Product { Name = "Assorted Cupcakes", Description = "Delectable vanilla and chocolate cupcakes", CreationDate = DateTime.Today, ExpirationDate = DateTime.Today.AddDays(7), ImageName = "cupcakes.jpg", Price = 5.99M, QtyOnHand = 12 };
My scenario is this:
I have asp.net page which having the drop down control with Product list. in database my Product Table has fields as ProductId, Product Name and Price. where as I have filled this drop down control by this method:
private void FillProducts()
{
List<Product> productList = objProductManager.GetProducts();
if (productList.Count > 0)
{
drpProducts.DataSource = productList;
drpProducts.DataTextField = "ProductName";
drpProducts.DataValueField = "ProductId";
drpProducts.DataBind();
}
}
Which is working perfect. But i want to get selected product Price value on client side. for that I don't want round trip at server to get that. is any property of dropdown control other than DataTextFeild Or DataValueField to hold the Price Field of product ? so that i would avoid to go back at server. Or suggest any remedy for the same.
Please guide me.
That's where Global variables and Session Variables takes place...
In a Web Environment you can have both, a Global Variable for cross users (where you can have the entire product list cached) or in a Session variable that you can use for only that user session.
You method would look like:
public MyPMan objProductManager = new MyPMan();
public List<Product> ProductList
{
get
{
if(Session["MyApp-ProductList"] == null)
Session["MyApp-ProductList"] = objProductManager.GetProducts();
return (List<Product>)Session["MyApp-ProductList"];
}
}
private void FillProducts()
{
//List<Product> productList = objProductManager.GetProducts();
if (this.ProductList.Count > 0)
{
drpProducts.DataSource = this.ProductList;
drpProducts.DataTextField = "ProductName";
drpProducts.DataValueField = "ProductId";
drpProducts.DataBind();
}
}
and you can easily, on submit or anything, just grab the price as
double p = this.ProductList.Where(x => x.ID.Equals(12)).Price;
This way, you only query the DB once per session, and it's available across the website, my suggestion is that you create a Static Business Object to be available every where and simply :)
then for example, you would do this as the first line
if (MyStaticObject.ProductList.Count > 0)
if you want to have the Product list across sessions and users, use the Application variable and set that in global.asax file.
added
How to do client validation using this:
I love jQuery Validation as it's the easiest and a fantastic client validation tool, so cool that even Microsoft now uses on ASP.NET MVC 2 and more in MVC3 ;)
you can easily pass values from ASP.NET into Javascript as
var myJavaScriptVariable = '<%= myAspVariable %>';
the other way around is more tricky ;)
and you can easily pass a JSON and use that JSON string, I would suggest Json.NET
Or you can use the built-in validation in ASP.NET WebForms... please provide what are you doing in your form (Repeater, GridView, List) in order to give you the exact code.
added (part 2)
to convert your Product List into a Json Array in javascript, you can do this:
in ASP.NET MVC 3
var jsonMVC = #Html.Raw(Json.Encode(reg));
in ASP.NET WebForms (using JSon.NET)
var jsonWebForms = <%= Newtonsoft.Json.JsonConvert.SerializeObject(MyStaticObject.ProductList) %>;
and then you can easily access all your object, for example:
var product = jsonMVC[0];
alert(product.Price);
There are more techniques, but I hope this ones helps.
Remember, I still strongly suggest that you use the built-in ASP.NET Control Validation, as you will have that out of the box, if you using a gridviewuse the RowDataBound Event to build up your stuff.
I would prefer an ajax solution here. Alternatively to Microsoft own UpdatePanel, an javascript/ajax/json call that sends the selected value in dropbox back to the server without reloading.
Speaking generically, one straightforward way to approach this in any web application would be to include an array of [ProductId,ProductPrice] with the page, independently from the dropdown, and use that in client-side JavaScript in conjunction with your 's current ProductId value.
You could always include a second dropdown which contains the ProductID-Price relation and hide is using css.
It would be as though you have a master-child table relation but with two dropdowns. The it's only a question of manipulating the dropdowns with, say, jQuery