As per title. I want to be able to save some data in a cache object but this object must be available to all users/sessions and can expire.
What is the best method to achieve this in a asp.net web app?
HttpContext.Current is available to all pages, but not necessarily to all threads. If you try to use it inside a background thread, ThreadPool delegate, async call (using an ASP.NET Async page), etc., you'll end up with a NullReferenceException.
If you need to get access to the cache from library classes, i.e. classes that don't have knowledge of the current request, you should use HttpRuntime.Cache instead. This is more reliable because it doesn't depend on an HttpContext.
HttpContext.Current.Cache will be present, but Current should only be used if you cant get to your context member.
Also to answer your second question, yes, the Cache object is global to the application.
Here's a good intro to caching...
How to cache in ASP.NET by using Visual C# .NET
and...
Caching with ASP.NET . Don't skip part 2, "Data Caching"
Related
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.
I know there is a very similar question here but I was hoping to get a better explination. Why would I ever use HttpContext.Cache instead of HttpRuntime.Cache if the HttpContext really uses the HttpRuntime.Cache behind the scenes?
In the article Simulate a Windows Service using ASP.NET to run scheduled jobs Omar uses the HttpContext to store his cache items, but when Jeff Atwood Implemented it here he chose to use the HttpRuntime instead. Obviously in this particular situation it makes sense since since you don't have to do a web request to add the cache item back into the HttpContext.
However I'm looking for some good pointers as to when to use one versus the other.
It really is the same cache at the end, only HttpContext.Current can sometimes be null (when not in a web context, or in a web context but not yet constructed). You'd be safe to always use HttpRuntime.Cache.
When you are in a regular web page, you can safely use HttpContext.Cache or just the Cache property of the page.
If you are doing something that's not in a page, you often need to use HttpRuntime.Cache to safely get access to it.
In some cases you can know if there is an http context or not, for example if you start a separate thread from a web page, that thread does not have http context. In other cases you may have an http context sometimes, like in the Application_Start method in global.asax, as the application may not always be started because there is a request.
I find it misleading too although we all know it just returns HttpRuntime.Cache internally. Also the HttpRuntime is kind of a bad choice to expose the Cache I guess.
Everyone sais how Session is session-level cache and the Cache we're talking about is application-level. I would prefer to have Application.Cache as the cache we're using today and HttpContext.Cache to refer to what's known as HttpContext.Items.
As for answering your question, I think we should all stick to the HttpRuntime.Cache making our code clearer even if we do have various ways to access it. And when you seriously plan to use it you'd better wrap your own API and have that internally call the HttpRuntime's or any other cache implementation (EntLib, Velocity, etc...).
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 doing some asynchronous work on a separate thread using:
ThreadPool.QueueUserWorkItem()
and in this separate thread, I need to call HttpContext.Current so that I can access:
HttpContext.Current.Cache
HttpContext.Current.Server
HttpContext.Current.Request
However, HttpContext.Current is null when I create this separate thread.
Question
How do I create a new thread so that HttpContext.Current is not null? Or is there another way I can access the Cache, Server, and Request objects?
You can access the ASP.NET cache with HttpRuntime.Cache even when you don't have a HttpContext, but unfortunately you cannot access Server or Request.
If you think about it, this make sense - you are not serving any page so you don't have a request.
I'd try not to hold a reference to an object that depends on the ASP.NET stack like the HttpContext. If you need to do some work in a different thread, it's because you don't want to wait in the ASP.NET one till your task is finished. And maybe the Request/Context/Session is terminated while your thread is not.
You should pass an object with the data needed for your thread.
1- Add bottom code in <system.serviceModel> in Web.config file:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
2- Add bottom code after NameSpace in web service file:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
3- Rebuild web part project.
Done!
reference
For HttpContext.Server services you can use HttpServerUtility class.
For the Cache you can use HttpRuntime.Cache, as it has been said above.
For the request object you can pass the data from the Request to the thread when it is created. Things like Request.QueryString or Request.Form... or whatever.
There is a thread pool implementation here that provides propagation of the calling thread's HTTP context. I haven't used it yet but I plan to.
If the separate thread is trying to access those objects, then yes they will be null. Those objects are scoped at the thread level. If you want to use them in a new thread you will have to pass them into the method/class where you need them.
Typically ASP.Net doesn't allow you to spawn new threads... Here is a post on the subject.
Here is a nice write up on threading in ASP.NET from MSDN.
I want to implement an ISAPI filter like feature using HttpModule in IIS7 running under IIS Integrated Request Processing Pipeline mode.
The goal is to look at the incoming request at the Web Server level, and inject some custom HttpHeaders into the request. (for ex: HTTP\_EAUTH\_ID)
And later in the page lifecycle of an ASPX page, i should be able to use that variable as
string eauthId = Request.ServerVariables["HTTP\_EAUTH\_ID"].ToString();
So implementing this module at the Web Server level, is it possible to alter the ServerVariables collection ??
HttpRequest.ServerVariables Property is a read-only collection. So, you cannot directly modify that. I would suggest storing your custom data in httpcontext (or global application object or your database) from your httpmodule and then reading that shared value in the aspx page.
If you still want to modify server variables, there is a hack technique mentioned in this thread using Reflection.
I believe the server variables list only contains the headers sent from the browser to the server.
You won't be able to modify either the HttpRequest.Headers or the HttpRequest.ServerVariables collection. You will however be able to tack on your information to any of:
HttpContext.Current.Items
HttpContext.Current.Response.Headers
Unfortunately, Request.Params, Request.QueryString, Request.Cookies, Request.Form (and almost any other place you'd think of stuffing it is read only.
I'd strongly advise against using reflection if this is a HttpModule you're planning on installing into IIS 7. Given that this code will be called for (potentially) every request that goes through the web server it'll need to be really fast and reflection just isn't going to cut it (unless you have very few users).
Good luck!