What is difference between normal cache class and MemoryCache class? - asp.net

What is the difference between normal cache class and MemoryCache class?
Cache means data stored in memory. Then why extra class given for MemoryCache?
What is the purpose of MemoryCache class and when is it used instead of normal cache class?
Just see the below example code
private void btnGet_Click(object sender, EventArgs e)
{
ObjectCache cache = MemoryCache.Default;
string fileContents = cache["filecontents"] as string;
if (fileContents == null)
{
CacheItemPolicy policy = new CacheItemPolicy();
List<string> filePaths = new List<string>();
filePaths.Add("c:\\cache\\example.txt");
policy.ChangeMonitors.Add(new
HostFileChangeMonitor(filePaths));
// Fetch the file contents.
fileContents =
File.ReadAllText("c:\\cache\\example.txt");
cache.Set("filecontents", fileContents, policy);
}
Label1.Text = fileContents;
}
What does the above code do? Is it monitoring file content change?

HttpRuntime.Cache gets the Cache for the current application.
see here
msdn
MemoryCache is a cache stored in memory.
Represents the type that implements an in-memory cache.
msdn
Here is an excellent blog that will clear all your concerns blog
Just few lines taken from this blog.
msdn says this
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.
Although Microsoft has always been adamant that the ASP.NET cache is not intended for use outside of the web. But many people are still stuck in .NET 2.0 and .NET 3.5, and need something to work with.
Microsoft finally implemented an abstract ObjectCache class in the latest version of the .NET Framework, and a MemoryCache implementation that inherits and implements ObjectCache for in-memory purposes in a non-web setting.
System.Runtime.Caching.ObjectCache is in the System.Runtime.Caching.dll assembly. It is an abstract class that that declares basically the same .NET 1.0 style interfaces that are found in the ASP.NET cache.
System.Runtime.Caching.MemoryCache is the in-memory implementation of ObjectCache and is very similar to the ASP.NET cache, with a few changes.

Related

Upgrade Issues .Net 6

IsMimeMultipartContent()
IAuthenticationFilter is not available
Read Multipart
HttpContextWrapper
I am expecting to identify how can I achieve these when I am upgrading the FW4.8 to .Net6
"CS1061: ActionExecutingContext does not contain a definition for
Request".
HttpContentMultipartExtensions.IsMimeMultipartContent is used to determine whether the specified content is MIME multipart content.
In Asp.Net Core, you can check that the request is multipart/form-data using property HttpRequest.HasFormContentType:
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
if (!actionContext.HttpContext.Request.HasFormContentType){}
}
You can also refer to Mathieu Renda's answer.
IAuthenticationFilter is not available.
Asp.net core doesn't contain the IAuthenticationFilter, if you want to authenticated the user, you can refer to Brando Zhang's answer.
Error: HttpRequest does not contain a definition for Content
You can take a look at this official document: Upload files in ASP.NET Core.
And you can also refer to these two posts to solve your problem: ReadAsMultipartAsync equvialent in .NET core 2, MultipartFormDataStreamProvider for ASP.NET Core 2.
Replacement for HttpContextWrapper
The HttpContextWrapper class derives from the HttpContextBase class and serves as a wrapper for the HttpContext class. So I think it is possible to access HttpContext directly in Asp.Net Core: Access HttpContext in ASP.NET Core.
Hope this can help you.

ASP.NET localization: Changing resources without restarting the application?

I have the requirement that the end-user can change localized resources and the changes should be visible in the application without the need to restart the application.
Update to clarify the scenario:
I am talking about changing the localized resources at runtime. Lets say I have a typo in the german translation of a page. Then some admin-user should have the possibility to change that typo at runtime. There should be no need for a redeployment or restart in order for this change to be reflected in the UI.
I am using ASP.NET MVC3.
What options do I have?
I have been looking into writing a custom ResourceProvider that loads resources from the database.
This seems not too much effort, however so far I pointed out two drawbacks:
It is not working with the DataAnnotations that are used for convenient validation in MVC3 (DataAnnotations work with a ErrorMessageResourceType parameter, which only works with compiled resources)
We basically have to provide our own tooling around managing resources (like translating etc.) which is a pity, since there are a lot of tools for this that work with resx-files.
What are the other options? Would manipulation of the deployed resx-files at runtime be an option?
But I suspect that the application is automatically "restarted" when it detects those changes: I suspect ASP.NET realizes that the resx-files have changed, it then recycles the application-pool and compiles the new resx-files on the fly.
Is this correct? Is there any way around this?
I have not yet looked into compiling the resources into satellite assemblies before deployment. Is this even a recommended scenario for web applications?
But even with compiled satellite assemblies I suspect that ASP.NET restarts the application, when those assemblies are changed on the fly. Is this correct?
I would be interested in any experience in how the original requirement can be satisfied?
And I would be interested in any comments about the options I have mentioned above.
DataAnnotations accept a ErrorMessageResourceType which tells the ValidationAttrributes where to access resources. You can pass this as follows:
[Required(
ErrorMessageResourceType = typeof(DynamicResources),
ErrorMessageResourceName = "ResourceKey")]
public string Username { get; set; }
By creating a type for this parameter with static properties for each key you can create an implementation that loads resources from a database or other implementation. You could then combine this with a dynamic object for DRY and move the implementation into TryGetMember. Potentially then use T4 templates to generate the statics from your database at compile time, ending up with this:
public class DynamicResources : DynamicObject
{
// move these into partial and generate using T4
public static string MyResource
{
get { return Singleton.MyResource; }
}
public static string MyOtherResource
{
get { return Singleton.MyOtherResource; }
}
// base implementation to retrieve resources
private static dynamic singleton;
private static dynamic Singleton
{
get { return singleton ?? (singleton = new DynamicResources()); }
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
// some logic here to look up resources
result = GetResourceKeyFromDatabase(binder.Name);
return true;
}
}
Of course it would be perfect if resources weren't static properties.

Ninject.Web (webforms extension), injecting outside of a webform page?

I've been using the Ninject.Web extension to inject business objects, repositories, Entity Framework context etc into my application. This works very well using the [Inject] attribute which can be applied within a webform that inherits from PageBase. I am now running into a snag as I am trying to write a custom membership provider that needs injection done inside of it but of course this provider is not instantiated from within a webform. Forms Authentication will instantiate the object when it needs it. I am unsure how to about doing this without having access to the [Inject] attribute. I understand that there is an application level kernel somewhere, but I have no idea how to tap into it. Any suggestions would be greatly appreciated.
You don't have to use the service locator pattern, just inject into properties of your custom membership provider in Application_Start. Assuming you've registed the providers properly you can do this with something like:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Inject account repository into our custom membership & role providers.
_kernel.Inject(Membership.Provider);
// Register the Object Id binder.
ModelBinders.Binders.Add(typeof(ObjectId), new ObjectIdModelBinder());
}
I've written up a more in depth explanation here:
http://www.danharman.net/2011/06/23/asp-net-mvc-3-custom-membership-provider-with-repository-injection/
You do a IKernel.Inject on the the instance. Have a look at the source for the Application class in the extension project you're using.
In the case of V2, it's in a KernelContainer. So you need to do a:
KernelContainer.Inject( this )
where this is the non-page, non application class of which you speak.
You'll need to make sure this only happens once - be careful doing this in Global, which may get instantiated multiple times.
Also, your Application / Global class needs to derive from NinjectHttpAppplication, but I'm sure you've that covered.
you may need to use the Service Locator pattern, since you have no control over the creation of the membership provider.

Using routing with webforms - CreateInstanceFromVirtualPath sometimes very slow

I am using routing with my ASP.NET WebForms application, using the technique described by Phil Haack:
http://haacked.com/archive/2008/03/11/using-routing-with-webforms.aspx
This works well most of the time, however on on occasion the first call to System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath is takes tens of seconds to return.
This happens in the following method:
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
LapTimer lapTimer = new LapTimer();
string virtualPath = this.GetSubstitutedVirtualPath(requestContext, lapTimer);
if (this.CheckPhysicalUrlAccess && !UrlAuthorizationModule.CheckUrlAccessForPrincipal(virtualPath, requestContext.HttpContext.User, requestContext.HttpContext.Request.HttpMethod))
throw new SecurityException();
IHttpHandler page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page)) as IHttpHandler;
if (page != null)
{
//Pages that don't implement IRoutablePage won't have the RequestContext
//available to them. Can't generate outgoing routing URLs without that context.
var routablePage = page as IRoutablePage;
if (routablePage != null)
routablePage.RequestContext = requestContext;
}
return page;
}
At the same time as this I notice (using Task Manager) that a process called csc.exe, the C# compiler, is taking up 10%-50% of my CPU.
Can anyone suggest why this would be happening?
Your application is using runtime compilation of views. While your business logic, codebehind etc (basically any .cs file) gets compiled by Visual Studio, your views (*.aspx, *.ascx, *.Master) are compiled by the asp.net runtime when a given view is first requested (i.e. the BuildManager is asked for an object that corresponds to a given virtual path). It might take some time because views might be compiled in batches (e.g. all views in a single folder).
A view will be recompiled if you change it. Also all view compilations will be invalidated if the App Domain recycles (which can happen if you make changes to web.config, global.asax, etc).
All this is normal behavior in ASP.NET. If you find that this is unacceptable in your scenarios you can use precompiled applications. This will provide you with app startup perf benefits at the cost of being able to easily tweak the markup of your site withouth having to recompile everything.

Problems with Web.config and App.config

Intro:
Normally we store ConnectionStrings and some other settings (<appSettings> <add key...) in the Web.config or App.config.
My scenery:
Web application using factory pattern
with direct injection to read data
providers.
In the web.config I have the key
that tells me which DLL (provider)
will I use to retrieve my data.
I can have more than one provider
(each DLL will be a provider for MS
SQL, MySQL, or get the data from
some SOA service).
Each DLL has his own name (ID and namespaces) and will need to have is own
configurations (dataconnections,
service urls, etc...) , the first
idea is to write then in the
app.config.
Problems:
#1 - The website is running (runtime) I need to change the Data Provider, how can I do this? Somehow the default value written in the Web.config will be changed.
My objective is to be able to have multiple providers (and during runtime: add/delete providers and change configurations) - this leads me to my second problem:
.
#2 - Each Data Provider has custom configurations and App.Config files do not work with dll assemblies, only executables. This means that I need to write then on my Web.Config (I do not like this option, because once again I am updating my web.config in runtime). how can I solve this?
I am trying to avoid to write a custom settings XML file. My ideal solution is to deploy somehow the DLL and DLL.config per each provider. And once again during runtime I may need to change this configuration values.
.
Ok guys, while I was waiting for some help I put my hands to work and I was able to find a good solution (in my opinion of course :P).
Let me share it with you:
So, I have one web application, or one console application, or some other kind of application, and lots of class library, and I need to store informations (different per Visual Studio project) that will change during runtime.
Storing this information inside the Web.config or App.config is not a good idea for the many problems it takes.
The other way I see it is to have one XML config file per project.
Each application will read his own XML and add it to the Cache with CacheDependency (will expire when the XML config file is updated). This way we will not need to read the configuration all the times, and we also know when the configuration is changed.
IMO THIS IS THE FASTEST AND EASIEST WAY TO SOLVE THE PROBLEM, no need to use 3rd party frameworks (neither the time it takes to learn/program it).
.
Example code:
protected void Page_Load(object sender, EventArgs e)
{
DBConfiguration cachConf;
cachConf = Cache["cachConf"] as DBConfiguration;
if (cachConf == null)
{
cachConf = new DBConfiguration();
XmlDocument doc = new XmlDocument();
doc.Load(HttpContext.Current.Request.PhysicalApplicationPath + "bin/MyConf.xml");
XmlNodeList xnl = doc.GetElementsByTagName("username");
XmlElement xe = (XmlElement)xnl[0];
cachConf.Username = xe.InnerText.ToString();
xnl = doc.GetElementsByTagName("password");
xe = (XmlElement)xnl[0];
cachConf.Password = xe.InnerText.ToString();
Cache.Insert("cachConf", cachConf,
new System.Web.Caching.CacheDependency(
HttpContext.Current.Request.PhysicalApplicationPath + "MyConf.xml"),
DateTime.Now.AddMinutes(60), TimeSpan.Zero,
System.Web.Caching.CacheItemPriority.Default,
new System.Web.Caching.CacheItemRemovedCallback(
CacheItemRemovedCallBack));
}
LabelUsername.Text = cachConf.Username;
LabelPassword.Text = cachConf.Password;
}
private void CacheItemRemovedCallBack(string key, object value, CacheItemRemovedReason reason)
{
//Response.Write("Hello world");
}
You could store the credentials in a secondary config file referenced from web.config as follows:
<appSettings file="AppSettings.config"/>
You would still need to be careful to avoid editing conflicts on the external file.
Problem 1 - Runtime changes:
The solution that Microsoft hopes you apply to this type of problem is to simply keep the web server stateless. When an ASP.NET application recycles, it lets existing requests complete new requests start on a new process. For background, read about IIS Process Recycling. A change to web.config recycle the worker process, but users will not notice this (unless you keep state in the web server process). That's the MS design.
If you want to monitor for changes without recycling a process, you'll want something other than default web.config behavior. An example that comes to mind are cruise controls project files. They have a component that maps objects to and from xml, using that, you can use the FileSystemWatcher class to monitor for changes.
Problem 2 - Custom configurations:
It sounds like you have components from different libraries that have different dependencies. Your main assembly needs a means to instantiate a service, with a given set of dependencies. The MS data provider model is cool, but not this cool.
To be this cool, use an inversion of control container, because this is exactly what they do. I like autofac (because I like the Philip K Dick reference), but castle windsor is great.
Now, if you are talking about changes databases or data providers on the fly, it may be that configuration is not the right place. If your are reporting against x databases of y types, you need a central repository of that database information, and a configuration file is not the right place, nor is an IOC container the right solution.
As Precipitous suggested, try Castle Windsor:
http://www.castleproject.org/container/
You're doing Inversion of Control manually. Windsor will take the burden off of you.

Resources