So I am having problems saving collections unique across tabs/browser (tabs really).
Using static variables to store data after the callback in ASP didn't work so well because all browsers could read from it and modify the variables.
Using session variables didn't work so well because while it successfully made the collection unique across browsers - it wasn't unique across tabs. So one Mozilla tab could modify a the collection in a session variable (the collection changes) - the user will get a nasty surprise when using another Mozilla tab when accessing the collection again - unfortunately the SAME collection - something like a dirty read.
So the problem is - how can I make collections across tabs/browsers stateful but uniquely stateful so that each can have their own unique collection and can modify it freely.
The problem as I see it here is one tab continually makes an ajax request which always recreates the controller object which means it will never be unique.
Another idea was to save a reference to this collection in javascript - and then pass this reference back and forth during each request - The problem is how can I do it without serializing/deserializing which kind of defeats the point of just saving the reference :(
Any ideas are welcome.
Methods that didn't work: Session, Application/Static (haven't tried Application but it seems to behave the same way).
Will ViewState work? It doesn't seem to save data however :'(
Replace the default route with a custom route which adds a GUID to the uri. And use that GUID to load the session.
I've made an example in my blog just for you: http://blog.gauffin.org/2012/02/get-a-unique-session-in-each-browser-tab/
You can store information into window.name, which should be unique per tab, since each tab is a different window.
Demo: http://www.thomasfrank.se/sessionvars.html
Related
For starters, please forgive me and please correct me on my terminology. I am quite sure of the correct words to use for what I am trying to accomplish.
I have been given the task of building an ASP.Net Razor web site. It is something new to me. I am very proficient in PHP and ASP Classic. What I need to be able to figure out is how to declare a variable that is accessible everywhere. I do not know if in the .net world you call it a global variable or application variable or something else. But, here is how I would do this in Classic ASP.
In Classic ASP, I would have a file named VarFunct.asp. It would be the file that I declare my variables and have various functions I would access from anywhere. I would include the VarFunct.asp file on all of my pages. Anyway this is what I am really trying to do (written in how I would do it in Classic ASP)…
SelLoc = Request("SelLoc")
If Len(Trim(SelLoc)) = 0 Then
SelLoc = "All"
End If
In this case, Request("SelLoc") could be Request.QueryString or Request.Form. Then anywhere in my website I could use the variable SelLoc. So, in short... I need to be able to set a variable. Check to see if it is set by Request.Form, if not, check Request.QueryString, if not set the value to “All”. How do I write this? And where do I put it?
When I created the website using Visual Studio 2012, I selected ASP.NET Web Site (Razor V2).
This seems like it should be such a basic fundamental task of any website that has any kind of server side programming, but trying to find information and documentation online is near impossible, but probably because I am not using the correct terms for my question. I have not found any Razor tutorials that talk about setting variables that can be used globally across the website.
If someone could please help me out here by either telling me what I need to do or point me to a good tutorial, that would be great.
what you are looking for is called Static Class/Member
This will allow you to store and share data for the whole application.
BUT! since web server is multi-threaded, you wouldn't want to do this or else you might run into the case where the data is overwritten by another request before you finished the current one.
If you need to pass data from controller to your View you can use ViewBag dynamic object
If you need to use the data anywhere else (for example in a helper class) then do
HttpContext.Current.Application["VariableName"] = something
It is basically a dictionary and each request will have a different Application object
There are several ways of doing this.
For your example I would assume that this particular variable can be different for different users that are using the application at the same time. This is more of a Session scope than Application scope.
In this case you could simply use inheritance and make a base controller and/or base view model class that all your other controllers and/or view models inherit from. This way you can pass it back and forth between the view and controller and read/update it whenever you need to.
You could also use the Request and HttpContext and Session objects that are built into asp.net, if they fit your need. A brief overview of some of their functionality can be found here: https://learn.microsoft.com/en-us/aspnet/web-pages/overview/api-reference/asp-net-web-pages-api-reference --- google searching specific ones yields tons of results.
If you truly want Application scope, you can of course use a static class for you utilize static methods. Then you don't need to include the class in every other class, but you would need to fully name qualify the method when you call it.
I would not recommend static variables at this level though. I can't imagine very many things that would need to change for every single user that you would change while the application instance is running. Most of these sorts of items that we use are caches (generally db lookups and such, that we don't want to retrieve from the db each time, and RARELY get updated). If you utilize caches, be very aware of your thread safety when updating them. Here is an msdn on caching: https://msdn.microsoft.com/en-us/library/aa478965.aspx --- Or application configuration settings, like the application environment. We pull most of those from a config file, and they are read only, we don't change them within a running instance of the application.
I'm trying to build REST API based on existing database model. I have already one built but I want to make it simpler and clear before I start coding client app. I've decided to use ASP.NET Core as back-end technology and WPF front end (also there will be Angular/Ionic frontend). The database model is very simple, it contains around 30 tables (different documents with related resources and collections).
So far API use flat URL - this way sometimes I have to post/put child object with its parent. Should I go with nested URL (API/Document/{id}/Item) to make sending object simpler or even use the only id which makes this object flat?
The second problem I have when I need data from child object for data needed to data grid source - should I add new method/controller to get ViewModel with all properties needed for data grid or should I get parent object collection first and then get child objects and construct view in client app?
Ultimately, this choice depends on many parameters and also on your team preferences. You didn't give enough details to give a absolute advice, but even though you did give them, there might not be any absolute answer anyway.
When in doubt, for both of your problems, I would recommend to go for the flat, simple, complete data transfer objects. (EDIT : of course won't be flat if you have linked collections, but still it would be simple and complete)
This has the advantage of reducing the number of connections / calls to the API, which have some overhead for all the network infrastructure, and for the client too.
Second, I think this simplifies development (but I admit this is debatable)
And also, about the second problem, it helps separate the concerns between your API and your client app. Building a ViewModel is often necessary (you maybe don't want to expose some informations, for security or performance reasons), but don't make it too complicated just for the client app; you want your API to be easily used by a new client / new version later.
To show you why it's usually worse to do many individual calls :
Imagine if you want to retrieve 40 documents.
If each document has Item1 and Item2, that would be 80 more calls if you have to retrieve Documents/1/Item1, Documents/1/Item2, etc.. !
Also, for your front-end development, you have to manage the callbacks (first call the document, once it's done get item1 and item2) which seems more complicated than getting the whole lot in one go (since ultimately you need to wait for everything to be there).
Worse, maybe some of the object has changed, and his children too, in between the call. You might end with Version A of your parent object, but with version B of it's children items !
Of course, there are some situations that could make the decomposed children items calls interesting.
If you often have to get only the item part of a document, without needing to reload the whole, that would be a good argument for that.
Or if the overall document is large, and you want to be able to display parts of the loaded documents before the complete loading is finished.
A last drawback I can see, when you have linked collection of related objects, is that you can have many repetition of linked objects. In this case it could make sense to do something more tricky if you need to avoid too many repetition, and have a few separate calls for main object, relations, and load related objects only once even if some are used multiple times can be beneficial.
My project group and I are to develop a generic workflow system, and have decided to implement a single Node (a task in the workflow) as a C# Visual Studio Web API project (Using the ASP.NET MVC structure).
In the process of implementing a Node's logic, we've come across the trouble of how to store data in our Node. Our Node specifically consists of a few lists of Uri's leading to other Nodes as well as some status/state boolean values. These values are currently stored in a regular class but with all the values as internal static fields.
We're wondering if there's a better way to do this? Particularly, as we'd like to later apply a locking-mechanism, it'd be prefereable to have an object that we can interact with, however we are unsure of how we can access this "common" object in various Controllers - or rather in a single controller, which takes on the HTTP requests that we receive for ou Node.
Is there a way to make the Controller class use a modified constructor which takes this object? And if so, the next step: Where can we provide that the Controller will receive the object in this constructor? There appears to be no code which instantiates Web API controllers.
Accessing static fiels in some class seems to do the trick, data-wise, but it forces us to implement our own locking-mechanism using a boolean value or similar, instead of simply being able to lock the object when it is altered.
If I am not making any sense, do tell. Any answers that might help are welcome! Thanks!
Based on your comments, I would say the persistence mechanism you are after is probably one of the server-side caching options (System.Runtime.Caching or System.Web.Caching).
System.Runtime.Caching is the newer of the 2 technologies and provides the an abstract ObjectCache type that could potentially be extended to be file-based. Alternatively, there is a built-in MemoryCache type.
Unlike a static method, caches will persist state for all users based on a timeout (either fixed or rolling), and can potentially have cache dependencies that will cause the cache to be immediately invalidated. The general idea is to reload the data from a store (file or database) after the cache expires. The cache protects the store from being hit by every request - the store is only hit after the timeout is reached or the cache is otherwise invalidated.
In addition, you can specify that items are "Not Removable", which will make them survive when an application pool is restarted.
More info: http://bartwullems.blogspot.com/2011/02/caching-in-net-4.html
I am forced to use static variables because of the asp.net execution path. I have to have the same variables on the master page as well as the page being called. Static variables make it very easy to carry over variables because they remain static. Unfortunately these variables hang in the ether of memory because the app hasn't actually "exited". Is there a way to destroy these variables when I finished used them? I looked into
IDisposable
but its implementation is not... clean. Is there a way to destroy variables when the page finishes rendering?
I am forced to use static variables because of the asp.net execution path. I have to have the same variables on the master page as well as the page being called. Static variables make it very easy to carry over variables because they remain static.
You aren't "forced" to use static fields just to share data between a master page and its content page. You probably don't want to either: static fields will be shared between all requests from all users of your application, which means they need to be thread-safe and limited to data that is shared between all users.
There are many techniques to share data between master and content page. For example, you could use the HttpContext.Items dictionary, which exists only for the duration of a single request.
For anyone looking for a way to "pretend" static variables, here is how you can go about it:
public static Datatype data
{
get
{
return (Datatype)HttpContext.Current.Items["DATA"];
}
set
{
HttpContext.Current.Items["DATA"] = value;
}
}
As far as I understand this doesn't necessary solve the "kill static" values, but it should avoid any data collisions caused by static variables. I had my entire project referencing the static variable and changing it would of created more messy code than should be seen. This way, when the call goes out to get "DATA" from your static object, it doesn't grab whatever pointed at but rather uses the context list which gets killed after and is unique to your session.
You can set them to null. If you're using ASP.Net WebForms you can do this inside the Page.Unload event handler.
You should avoid using static properties in your master page and use Session[""] variables, they will be destroyed when the user ends the session.
Without knowing your setup, and thinking in a future of cloud environment as well, where you can have more than one server answering user requests and, you have no idea if the same server will answer all the requests of that user or the load balancer ask the other servers to continue, I would, as I currently do, give you 2 options
Before the options, in a Web Environment, it is good pratice to stop using Sessions or Static variables (for the reason above)
Use cookies
Why not use a cookie to pass value from one place to the other and when consumed, simply write the expiration data back one year and the cookie is gone!
Use MemCached
I always have a Cache layer between my application and the database, and it's the best way to keep values, not only from the database to provide to all users, but a good way to keep variables when we need cross application.
MemCached is free and runs fine on windows, plus there are several Cloud Services that offer this in their servers
I like to implement a collection (something like List<T>) which would hold all my objects that I have created in the entire life span of my application as if its an array of pointers in C++. The idea is that when my process starts I can use a central factory to create all objects and then periodically validate/invalidate their state. Basically I want to make sure that my process only deals with valid instances and I don't re-fetch information I already fetched from the database. So all my objects will basically be in one place - my collection. A cool thing I can do with this is avoid database calls to get data from the database if I already got it (even if I updated it after retrieval its still up-to-date if of course some other process didn't update it but that a different concern). I don't want to be calling new Customer("James Thomas"); again if I initted James Thomas already sometime in the past. Currently I will end up with multiple copies of the same object across the appdomain - some out of sync other in sync and even though I deal with this using timestamp field on the MSSQL server I'd like to keep only one copy per customer in my appdomain (if possible process would be better).
I can't use regular collections like List or ArrayList for example because I cannot pass parameters by their real local reference to the their existing Add() methods where I'm creating them using ref so that's not to good I think. So how can this be implemented/can it be implemented at all ? A 'linked list' type of class with all methods working with ref & out params is what I'm thinking now but it may get ugly pretty quickly. Is there another way to implement such collection like RefList<T>.Add(ref T obj)?
So bottom line is: I don't want re-create an object if I've already created it before during the entire application life unless I decide to re-create it explicitly (maybe its out-of-date or something so I have to fetch it again from the db). Is there alternatives maybe ?
The easiest way to do what you're trying to accomplish is to create a wrapper that holds on to the list. This wrapper will have an add method which takes in a ref. In the add it looks up the value in the list and creates it when it can't find the value. Or a Cache
But... this statement would make me worry.
I don't want re-create an object if
I've already created it before during
the entire application life
But as Raymond Chen points out that A cache with a bad policy is another name for a memory leak. What you've described is a cache with no policy
To fix this you should consider using for a non-web app either System.Runtime.Caching for 4.0 or for 3.5 and earlier the Enterprise Library Caching Block. If this is a Web App then you can use the System.Web.Caching. Or if you must roll your own at least get a sensible policy in place.
All of this of course assumes that your database's caching is insufficient.
Using Ioc will save you many many many bugs, and make your application easier to test and your modules will be less coupled.
Ioc performance are pretty good.
I recommend you to use the implementation of Castle project
http://stw.castleproject.org/Windsor.MainPage.ashx
maybe you'll need a day to learn it, but it's great.