For example, in a ASP.NET page you would do something like
Cache.Add({...}) and access it via Cache["key"]. In this context, Cache is the System.Web.Caching.Cache object.
Is there anyway to do this type of ASP.NET application level caching in web API controllers?
Take a look at the MemoryCache class. From its MSDN documentation:
The MemoryCache class is similar to the ASP.NET Cache class. The
MemoryCache class has many properties and methods for accessing the
cache that will be familiar to you if you have used the ASP.NET Cache
class. The main differences between the Cache and MemoryCache classes
are that the MemoryCache class has been changed to make it usable by
.NET Framework applications that are not ASP.NET applications.
You can create a new instance of a MemoryCache yourself, or you can use the default AppDomain-wide instance via the MemoryCache.Default static property.
Edit: You'll need to add a reference to System.Runtime.Caching.dll if you wish to use this type.
If you are web hosting, why not?
var context = HttpContext.Current;
if (context != null)
{
if (context.Cache["g"] == null)
{
context.Cache["g"] = 9.81;
}
}
But you are adding a dependency on ASP.NET by doing so. Even though ASP.NET Web API has ASP.NET in the name, the Web API is host-agnostic. That is, ASP.NET/IIS is not the only hosting option; the Web API can be self-hosted as well. Something for you to consider before going down that route.
You need to type
HttpContext.Current.Cache
to access the instance. There is no Cache property declared at the Controller level, like on a Page.
Note that the context that hosts the API will need to support caching.
If you are referring to Output caching in ASP.NET Web API. Take a look at this project,
https://github.com/filipw/AspNetWebApi-OutputCache
Related
Where can I extend ASP.NET current (5.0) Identity functionality to easily resolve the integer user ID and security rights associated with a claim?
This should be available within all of my web application browser service access points (everywhere a cookie or JWT is provided), including SignalR hub, MVC controller, and WebAPI controller. It should work with OWIN Authentication.
Here are the three most-related solutions I've seen, and why they don't work:
Set HttpContext.Current.User in every call via global.asax Application_PostAuthenticateRequest. I've seen older (MVC 4) functionality that obsoletes this. I know global.asax is generally not the way to go today. I'm also using OWIN; this may not even work at all.
Override ClaimsPrincipal ClaimsAuthenticationManager.Authenticate() with the configuration <system.identityModel><identityConfiguration><claimsAuthenticationManager type = "CustomClaimsAuthenticatonManager" /> However, ClaimsAuthenticationManager is from System.Identity, which isn't even in the references of my ASP.NET 5.0 project with ClaimsAuthentication active. Instead I have references to Microsoft.AspNet.Identity.Core stuff in my project from current NuGet packages. It seems this approach is not for ASP.NET apps, or at least not current ones?
Set UserManager.ClaimsIdentityFactory to a custom ClaimsIdentityFactory, with overridden CreateAsync. This looks like this might work, but I don't see any way to graft that onto the current ASP.NET default behavior. See here: How to set a custom ClaimsPrincipal in MVC 5?
I need to run my application which provides some ASP.NET Web API services on both IIS and .NET CLR self host modes.
I developed my ASP.NET Web API services based on OWIN and it is working fine on both hosts.
For now I need something like this:
public class OwinContextInfrastructure
{
public static IOwinContext Current
{
get
{
if (HttpContext.Current != null)
{
return HttpContext.Current.GetOwinContext();
}
else
{
// What should I do here ?
return null;
}
}
}
}
to get current owin context whenever I need in my application.
My code is working fine on IIS, but what should I do in .NET Self Host mode ?
You can use Request.GetOwinContext() for both web-hosting and self-hosting. GetOwinContext is an extension method for HttpRequestMessage and is defined in the System.Web.Http.Owin.dll assembly.
UPDATE
I have answered your original question, which is how to get OWIN context in both web-hosting and self-hosting. Now, through your additional question in the comment, you have significantly broadened the scope of your question. There is a fundamental problem though. IOwinContext is not a OWIN thing, it is a Katana thing. You cannot expect any framework hosted on OWIN to provide a context in the form of IOwinContext. ASP.NET Web API does but not every framework is supposed to. IOwinContext is an abstraction over OWIN environment dictionary and this dictionary will be available to any OWIN middleware. However, by working on top of a framework, you no longer can access the OWIN environment directly but only through how that specific framework has decided to expose the context.
For Nancy, you have to use NancyContext to get to the Items dictionary and look for the value corresponding to the key "OWIN_REQUEST_ENVIRONMENT". For SignalR, Environment property of IRequest gives you access to OWIN environment. Once you have the OWIN environment, you can create a new OwinContext using the environment.
First, I've to correct my question.
HttpContext.Current is available in applications which are based on ASP.NET and integrated IIS pipeline.But We can't use this class without asp.net anywhere, even on IIS integrated pipeline.
Answer:
1- Anywhere you need IOwinContext, you've to get it, using dependency injection, for example by constructor injection.
2- Configure everything to work based on Owin, SignalR is Owin based only, but use Web Api & owin together, and use nancy for server side views if any. Instead of writting IIS or ASP.NET handlers and modules, develop owin middlewares.
3- Using Autofac.Owin & AutoFac.WebApi & AutoFac.WebApi.Owin & Autofac.SignalR, you can setup dependency injection working across all owin middlewares you've in your application.
4- Autofac will instantiate web api controllers, signalr hubs and owin middlewares, and it will pass IOwinContext instance to classes you want using constructor injection.
My tests are ok on Owin IIS/Helios (without asp.net) , Owin SelfHost and even Owin Test Server.
This approach is similar to asp.net vNext. You can easily migrate your app to asp.net vNext, when it is production ready.
I've got two different, but closely related ASP.Net web applications that use the same data on some pages. In both applications I am using the ObjectDataSource control, have EnableCaching="true", and use the same CacheKeyDependency value in both applications.
I would like to make it so that when a new record is inserted or deleted in one application, it clears the cache in both applications. I began by simply clearing cache by using Page.Cache, but soon realized that it does not clear the cache in the other application. Then I added a WCF service to each application; each service clears the cache object in the application it is hosted in. Except that it doesn't...
First, I discovered that System.Web.HttpContext is always null in WCF. Then I tried instantiating a System.Web.Routing.RequestContext object, but its HttpContext object is always null as well.
It all boils down to this: If I set a Page.Cache object, can a WCF service access that same cache object, if the service is hosted in the same application as the page?
Yes, you need to enable ASP.NET integration for the WCF service. This involves setting the aspNetCompatibilityEnabled attribute for the serviveHostingEnvironment element in config as well as adding the AspNetCompatibilityRequirementAttribute attribute to you service class to indicate that you support it.
More on this subject can be found here on MSDN.
The main challenge with cache in two applications is that the cache can be stored on seperate machines, or if they are on the same machine, in different application pools.
One way you can do this is to allow both applications to use the same cache. One solution for a distributed cache that runs out of process is Appfabric caching.
What is the difference between System.Web.Cache and HTTPContext.Curent.Cache? In which cases both are used?
System.Web.Caching.Cache: this is the
implementation of .NET caching.
System.Web.HttpContext.Current.Cache:
this is the instance of that
implementation, that lives in the
application domain.
The Cache class is not intended for
use outside of ASP.NET applications.
It was designed and tested for use in
ASP.NET to provide caching for Web
applications. In other types of
applications, such as console
applications or Windows Forms
applications, ASP.NET caching might
not work correctly.
From msdn article
System.Web.Cache is the class of the caching, and HttpContext.Current.Cache is a property that returns a reference to the caching object in the application.
The Page, UserControl and HttpResponse objects also have a Cache property that you can use to get the reference. You can also get the reference from HttpRunTime.Cache.
System.Web.Caching.Cache is class that handles cache and HttpContext.Cache is property, that contains an instance of System.Web.Caching.Cache for current context.
System.Web.Caching.Cache is the implementation of .NET caching (1).
System.Web.HttpContext.Current.Cache is the instance of that implementation, that lives in the application domain (1).
(1): Reference
I have a home-grown framework that includes a simple ServiceLocator class implemented using a static Dictionary. It was developed for a WinForms environment and did what I wanted just fine.
This proves to be a disaster when using the framework in as ASP.Net framework; the Dictionary, a static variable, is instanciated upon first use and every ASP.Net application uses the same dictionary. This is NOT my design intent.
For example, the a web application attempts to register a DB Audit Service, IAuditService. Error!! The service is already registered by the first user! Just the tip of the static variable problems that can occur in a ASP.Net environment.
I have experimented with Autofac IOC. Can I avoid my static variable problems by using Autofac (or some other IOC)?
BP....
You can use an IOC framework, but if you want the object to stick around you will have to store it yourself, otherwise you will just be asking for a new object each time from the IOC Container.
I add a new instantiation type to my ServiceLocation specific to a web application.