I am in a situation where requirement is to keep an application level object in web api which can be accessed by all requests. I know one can use HttpContext.Current but that is not required since HttpContext is only for the liftime of request. I need a solution where i can keep an object that all requests can access and update as required.
Use a static class to hold your application level objects. static classes and static data members are created once for the application lifetime and all ASP.NET requests can access them.
I learnt it the hard way. Some time back, I mistakenly created a static field to hold customer-specific database connection string, in a ASP.NET Web API project and it became a mess. On each customer's login it was being set (overridden) in the code and the requests from the previously logged customers were using this newly set static SQL connection string for their queries. It was an embarrassing situation when customer's inadvertently saw each other's data.
You could use SessionState (per session).
I.e.
Session["YourDataKey"] = ApplicationLevelObject;
And then check the session state variable on each request that requires it.
However if you require the object for longer, I.e. every single user session, then I would suggest persisting your object to a database. You could use an ORM such as Entity Framework.
Cheers
Related
I have a ASP.Net API implementation, where to store and access the data / variables across consecutive calls, I am using a session state object as shown below and it can be successfully accessed in the multiple calls to separate calls by a browser:
// Access the current session object
var blSession = HttpContext.Current.Session;
// create the BL object using the user id
BL accessBL = new BL(userID);
// Store the Bl object in the session object dictionary
blSession["UserBL"] = accessBL;
I have to enable the following setting in the Global.asax, for the Session object to be accessible:
protected void Application_PostAuthorizeRequest()
{
// Enable session state in the web api post authorization
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
}
Issue comes in when the WebAPI shown above has to be accessed via another ASP.Net MVC client, which is separately hosted on a different machine, at that time same consecutive calls do not maintain the state as shown above and thus it leads to an exception, since the consecutive calls rely on session data to proceed.
I have seen a similar issue when I seen the similar issue when I use the Fiddler Debugger, as it gets hosted as a web proxy, so consecutive calls through that too fails, since it does not maintain the state. In my understanding, issue is due to setting the Cookie across domain, which doesn't seem to work across domains due to security reason
I know a workaround is to use an application wide variable like Cache, but please suggest if you have a way to get the SessionState work. Let me know if you need more details.
If you have not setup an alternative way to do SessionState, then the default behavior is to do it InMemory on the server. This is why you are seeing issues when the request is handled by a different ASP.NET server.
Web API calls are meant to be stateless. That is, they should not perform like a classic ASP.NET application that relies on the framework to store user specific information in Session variables across HTTP requests. For each call, pass in a user-specific identifier or token that you can then use to lookup information stored in your backend. You can store this information in your database or a distributed cache like MemCache for faster retrieval.
Is there any way to use caching in ASP.Net except SQL Server second level cache. As it is the first time to work with caching I want any way with an example. I have found that NHibernate implements this but we are using .netTiers as an application framework.
The Session cache seems to be the appropriate caching mechanism here. The Session cache is a fault-tolerant cache of objects.
Inserting an object
Session["Username"] = "Matt";
Reading an object
string username = (string)Session["Username"];
Removing an object
Session.Remove("Username");
I say fault-tolerant because if the value with the key you specify doesn't exist in the Session cache, it will not through an exception, it will return null. You need to consider that when implementing your code.
One thing to note, if you are using Sql Server or State Server, the objects you can put in the cache need to be serializable.
Memcached is also a very good way to go, as it is very flexible. It is a windows service that runs on any number of machines and your app can talk to the instances to store and retrieve from the cache. Good Article Here
I'm working with a project in ASP.Net using Webforms. I'm using Entity Framework to save data on Microsoft SQL.
My question is:
Is possible to use a Static class to keep the ObjectContext of EF live and put/get entities NOT saved inside the ObjectContext?
I want to create an Object, then added with AddObject on the ObjectContext, But NOT to do the Savechanges. All this in one webform. And then, in other webform, access to the ObjectContext and get the Object when added.
It is this possible?
My rules to using ObjectContext:
Do not use static context.
Do not share context.
You are trying to violate both rules. If you do that your application will have undeterministic behavior. Create new ObjectContext instance for each request. It is the same as openning new connection and starting new transaction in the request instead of sharing one connection and one transaction among all of them.
Further explanation also here. Also check linked question in right column and you will see what type of problems people have just because of violating one or both mentioned rules.
Also in web application it becames even more interesting because ObjectContext is not thread safe.
You could add it to the application items collection. See this blog post for syntax and such.
http://www.informit.com/articles/article.aspx?p=27315&seqNum=3
Generally, you don't want to. An ObjectContext is intended to be a unit of work, alive for a single set of related transactions. In an ASP.NET application, that generally corresponds to a single request.
If you must keep it alive for multiple requests, I wouldn't use either a static class, nor the application context. Instead, I'd recommend using the Cache, and then attaching the callbacks to it that let you ensure all your transactions are committed before it gets evicted, just in case.
In an ASP.NET web app written in VB.NET, I need to load and store a large read-only hash table that is frequently accessed by the application. It only needs to be loaded once on application start, is never updated and can be accessed by any session at any time.
If I load the hash table into a private member in a (global) module, a lookup to it takes one 20th of the time compared to storing the hash table in the Application or Cache object. Is there any reason why I should not do this, or should Application or Cache always be used to store in-memory objects in an ASP.NET web application?
Since they are thread-safe I would recommend you to use Application or Cache object (in your case application object is more convenient). Of course, you may choose to implement your own but consider thread-safety.
I'm making a .net component, resulting in a dll assembly, that will be referenced by an asp.net site, and in another project by an asmx webservice. All code is version 2.0.
The component has a few functions that call an external webservice, which returns an object. One of these functions is for example Login(username, password), which generates amongst others a unique session id for this user. The resulting information and session id are stored in variables in the component.
The issue in the website is:
When the user logs in in the frontend, and my component gets called and checks the login and generates the session id, I want that information in my component to persist when the user browses to another page in the site.
The issue in the web service using my component is:
I don't really care much about session state, but I want the component to just work. If per call a new session id is generated, that's okay.
The combination of the two environments causes the following problem for me:
I can't use the asp.net Session() variable in my component without referencing system.web, which is kinda silly and might not be available in the web service project that includes my component
I can't program my component as a singleton, because then in the website application, it's shared amongst all visitors, overwriting sessions and whatnot
making an array of "session information" in my component and maintaining that is hard to program (when does it get invalidated?) and might not work in a web farm environment
Is there a solution to this situation? Or should I make two instances of my component, one for use in websites, and one for use in web services?
Perhaps I'm not understanding what your asking but why can't you do something like:
Component.Login(user,pass);
Session["Component"] = Component.SessionID
I've created an extra class "Factory" which has a .Create(byref Session as HttpSessionState), that looks if the passed in session object is Nothing, if not, it checks if there is a Component object in it, if so, it uses it, if not, it creates it and adds it to the session.
In the case of the webservice call, the factory gets the Nothing-parameter, so it doesn't check in the session object. It seems to work.
Thanks for your answers!