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
Related
Is it a bad idea to implement my own session state provider that conditionally switches based on key between the redis session provider and the inproc session provider?
I am working in a very large legacy asp.net application that currently uses the inproc session provider. We are migrating to Redis as a session state provider so that it persists deploys, however the application is chock full of session abuses (e.g. way too large objects, non-serializable object, I saw a thread in there for some reason?).
We plan to slowly correct these abuses but until they are all corrected we cannot really move to redis. I am hoping we can slowly start migrate serializable-safe keys into redis while the abuses remain in memory until we address them.
Does anyone have any advice on this? Or perhaps alternative suggestions for migrating to out of process from in process?
Thanks!
In ASP.NET Web Form and MVC, using Redis for Session State is just a couple of line of modification in Web.config. Then add SerializableAttribute to classes. There is no side effects of applying it to a class.
Based on my experience when migrating to Azure few years ago, Session State is not worth migrating slowly.
Caching is different story. It requires code changes, so we end up implementing two classes - MemoryCacheManager and RedisCacheManager, and register at run-time in IoC container. Then inject ICacheManager to dependent classes.
Source for the session state: https://github.com/Microsoft/referencesource/blob/master/System.Web/State/
Docs: https://learn.microsoft.com/en-us/dotnet/api/system.web.sessionstate?view=netframework-4.7.2
I'd start by checking out the reference source so you can search the codebase. One interface jumps out as potentially interesting.. IPartialSessionState (When implemented in a type, returns a list of zero or more session keys that indicate to a session-state provider which session-state items have to be retrieved.) Source is here
https://learn.microsoft.com/en-us/dotnet/api/system.web.sessionstate.ipartialsessionstate?view=netframework-4.7.2
I stumbled on https://www.wiktorzychla.com/2007/06/wrapped-inprocsessionstatestore.html
via ASPNET : Switch between Session State Providers ?.
This technique could theoretically be used with the Redis provider as well. You'd have to either maintain a list of keys suitable for storing in Redis or do some kind of try to serialize/catch/cache result of which types can be serialized and adaptively fall back to the InProc behavior. You should be able to use HttpContext.Current.Items to flow information between events in the request processing pipeline.
The SessionStateModule (the module responsible for retrieving session, locking, saving, unlocking, etc.) seems to treat InProc as special in a few places. Search its code for InProc. Essentially you're trying to plug in a magical provider that is Custom and yet still has all of the InProc semantics applied by the one and only SessionStateModule. You won't be able to/probably won't want to modify that module, but you may be able to hook up another one adjacent to it that hooks into related events in the request pipeline and does whatever needs to be done that is either In-Proc or Custom-specific. You'll probably run into internal/private methods for which you'd need to use reflection. Not sure how the licensing works on the reference source (MS-PL I think), but another option would be to copy & paste the code from SessionStateModule into your own, make adjustments as needed, unregister the original and register your replacement.
I think you're going to be stuck dealing with a lot of reflection code to get this to work.
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
maybe the question is wrong but here is what i want to achieve maybe there is other way to do that.
I have ASP.NET application running .net 3.5, there is a client list and few others List based objects that are shared among all users of application. ie. when client logged in his userID and few other properties are saved within some List in Application state. Problem is that this application is heavy and it's application pool needs to be restarted once a day or so so all the information saved in these List objects is lost. While client personal data which is saved in Out-of-Proc mode on external server is saved.
Is there any way to workaround it ? Shared Session? Something like that.
PLEASE NO MSSQL SOLUTIONS...
Cheers, pros !!!!
Have you looked at caching the lists of data?
This SO article has some good detials.
You should only use Application State as a cache for data persisted elsewhere. You would then use Application_Start or some Lazy loading wrapper class to retrieve such persisted data into the application object.
If you are storing volatile data not persisted elsewhere in the application object then you are in trouble. Hopefully you would have abstracted access to the application object behind some wrapper object so that all your code is accessing the wrapper not tha application object. Now you would need to ensure the modifications are saved elsewhere so that they can be recovered on restart.
To be frank the Application state object is really an aid in porting ASP-Classic sites. Since you should really just treat the application state as a cache, there is an overlap in functionality between it and the ASP.NET Cache object.
I'm trying to cache some information that I've retrieved from a database. I've decided to use a static List<> member to store the information. I know from my experience with List<> in multithreaded applications that I need to protect access to it with the lock statement. Do I treat any code in my Asp.Net code the exact same way? Will the lock statement still work?
A lock statement around List method's would definitely work but if you need caching functionality in your ASP.NET application I would recommend you using Cache class which is adapted to this functionality.
Lock will work. Be aware that if there are multiple worker processes, you will end up with multiple versions of the list. Each of them will be protected by its own lock.
A pretty real danger here is that if you fail to release the lock, your entire web application might hang. A user might get disconnected while your ASP.NET page is executing; so be careful of exceptions thrown at unexpected times.
It depends upon whether you're going to modify the List. Here's a good discussion of this subject: Do i need a lock on a list? C#
I am implementing NHibernate into an existing web application. However, we have some other processes that do bulk inserting and updating on the database. How can I make NHibernate aware that changes are occurring on the backend db that were not initiated through NHibernate?
Most of the info that I have read around NHibernate use in asp.net have mentioned storing the Session object in the HttpContext or CallContext. This would then store the session object for the duration of the application lifecycle. This is what I have implemented. I was afraid of the costs of initializing NHibernate on each request. Isn't there a significant performance hit with this approach with initializing the Session object on each request?
Also, would it make more sense to store the SessionFactory in the the HttpContext or CallContext so that the mappings don't have to be regenerated on each request?
You shouldn't. NHibernate sessions are there to help you work in an ACID environment, which means that one transaction is not aware of any concurrent transactions. You should be using short sessions which do small sets of actions. You should not be holding sessions open for long periods of time. If you do need long periods of time for working with domain objects, then you should be detaching and then re-attaching the domain objects from and to different sessions.
Once you open a new session, any changes done to the database before the session was opened will be made available through NHibernate.
You should not store the Session over multiple requests. Bad, bad idea.
There is little to no overhead with recreating it on every call. It should use database connection pooling - which is where the bulk of the overhead would be.
By default NHibernate will not cache anything between sessions. If your sessions are short lived (per request), you shouldn't have much to worry about.
If you are using second level caching or query caching though, you may need to flush the cache manually. SessionFactory.Evict or SessionFactory.EvictQueries should help there. Restarting the app should also do it, but that's probably not the answer you're looking for.
In an ASP.NET app, the general usage I've seen is to create one SessionFactory for the app and create a new Session for each request.
The SessionFactory takes a while to initialize, is thread safe, and only needs to be initialized once.
The Sessions are not thread safe and are pretty quick to create.
Anything stored in the HttpContext will only be alive for the length of the request. Storing the session in the context is normal and should give you the desired result. The SessionFactory is usually stored in a static variable and will last as long as the app.
See the NHIbernateHelper class here for an example.