I am working on website which stores important data in HTTPContext.Cache for fast performance. If any data is changed during the day time. we have automated process to clear and regenerate the cache. But the problem is when cache is getting generated any user trying to access the website gets error.
I am looking for a solution to this problem. Where i can stop the request to website till cache generation is not finished.
One is to put app_offline file and delete it when cache is fully refreshed.
Please do let me know if you need more information
You can use the global.asax and do something like
protected void Application_BeginRequest(Object sender, EventArgs e)
{
if(fCacheIsNotReady)
{
HttpContext.Current.Response.TrySkipIisCustomErrors = true;
HttpContext.Current.Response.Write("We not build our site, please try again in few seconds.");
HttpContext.Current.Response.StatusCode = 403;
HttpContext.Current.Response.End();
return ;
}
}
The fCacheIsNotReady can be global static parametre that is true, when you start build you cache, and false when you end,
You can also check what files are you going to stop.
I do not know how you create your cache, you may also use some lock() to hold the users until the cache is made.
Related
My website is running on ASP.NET platform and recently i test my website on pingdom and i found the below error.
Resources with a "?" in the URL are not cached by some proxy caching
servers. Remove the query string and encode the parameters into the
URL for the following resources:
https://projectsdeal.co.uk/ScriptResource.axd?d ...
63Nawdr4rAt1lvT7c_zyBEkV9INg0&t=ffffffffe3663df5
https://projectsdeal.co.uk/ScriptResource.axd?d ...
JGTlZFM0WRegQM9wdaZV3fQWMKwg2&t=ffffffffe3663df5
Simple leave it as it is (its not an error !) - you can not remove this query string from resource because this is the id on how to load that resource from asp.net
The message that you get is actually talk for a proxy caching servers - what is a proxy caching server ? a middle computer that cache pages of your site, not the actually client computer - that can hold in cache that page and not bring slower your site in general.
So your client can hold that resource on cache if you set them correctly, and from what I see asp.net take care correctly and you resource are cached just fine - see this screen shot.
Now if you wish to add even more aggressive cache you can use the global.asax and do something like
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string cTheFile = HttpContext.Current.Request.Path;
if (cTheFile.EndsWith("WebResource.axd", StringComparison.InvariantCultureIgnoreCase))
{
JustSetSomeCache(app);
}
}
private static void JustSetSomeCache(HttpApplication app)
{
app.Response.Cache.AppendCacheExtension("post-check=900, pre-check=3600");
app.Response.Cache.SetExpires(DateTime.UtcNow.AddHours(32));
app.Response.Cache.SetMaxAge(new TimeSpan(32, 0, 0));
app.Response.Cache.SetCacheability(HttpCacheability.Public);
app.Response.AppendHeader("Vary", "Accept-Encoding");
}
What is the different ? The second cache is not check the server at all for file change as the asp.net do, you can gain one webserver call.
I'm about to include this into our build:
void Application_PreSendRequestHeaders(Object sender, EventArgs e)
{
// Cache only on the server and the client (if SSL is disabled)
// This doesn't determine what should be cached, only where
// cacheable items are allowed to be stored.
Response.Cache.SetCacheability(HttpCacheability.Private);
}
First off, are my comments in the code correct?
Second, is this an OK action to take? Is it fine to set a cache-control header for all requests? Most my reading, people set cache headers per directory.
I assume this should probably be done in IIS, but we are running in azure so its a little trickier making IIS changes (have to automate it).
I have made a custom error page for my ASP.NET 4 application. I put the exception object in HttpContext.current.Session["CustomError"] but when the user is redirected to the error page HttpContext.current.Session["CustomError"] is null.
I do it in CustomError class constructor like this:
public CustomError(enExceptionType ExceptionType) : base(ExceptionMessage(ExceptionType)) {
HttpContext.Current.Session["CustomError"] = this;
}
when I step over the code Session["Error"] contains the error object.
any idea?
UPDATE:
I removed custom error page from web.config and added this to glabal.asax:
void Application_Error(object sender, EventArgs e)
{
if (Context.IsCustomErrorEnabled)
{
Response.Redirect("~/Error.aspx");
}
}
by stepping through this function I noticed that when an exception is thrown this function is called two time, the first time Session["CustiomError"] contains the error object but the second time its null.
Instead of using Response.redirect(URL) (which I assume you have in your code) use
Server.Transfer(URL)
or
Response.redirect(url, false)
Why Server.Transfer(url)?
Transferring to another page using
Server.Transfer conserves server
resources. Instead of telling the
browser to redirect, it simply changes
the "focus" on the Web server and
transfers the request. This means you
don't get quite as many HTTP requests
coming through, which therefore eases
the pressure on your Web server and
makes your applications run faster.
Source here.
Please let me know if one of these works for you.
UPDATE:
If you use a web config setting can you try adding ResponseWrite value to redirectmode var?
<customErrors mode="RemoteOnly" defaultRedirect="~/errors/GeneralError.aspx" redirectMode="ResponseRewrite" />
If this is still not working I suggest to implement this (I've done it in my application to log the errors in log files (for me as admin) and present a generic error to the user).
This solved the problem, but I would appreciate it if someone tells me why :)
void Application_Error(object sender, EventArgs e)
{
if (Context.IsCustomErrorEnabled)
{
Response.Redirect("~/Error.aspx");
**Server.ClearError();**
}
}
I have a simple 'file download' generic handler which sets the response contenttype and headers before sending the file through the same response.
I also have Response.Cache.SetCacheability(HttpCacheability.server) set in the global.asax.
As I have noticed from various sources, Internet Explorer doesn't like this no-cache setting and gives an error when trying to download the file (requested site unavailable or cannot be found).
I thought maybe I could override this setting in the .ashx page, so I alter the response's cacheability setting to public. This did not solve the issue... removing the line from global.asax does solve the problem but obviously affects the whole site.
Is there a way of setting the cachability just for my generic handler?
Cheers :D
Can you just check whether the request is made to your generic handler and provide the appropriate cache settings depending on the result ? Something like this:
public void Application_OnPreRequestHandlerExecute(object sender, EventArgs e)
{
if (!HttpContext.Current.Request.Url.AbsolutePath.EndsWith("MyHandler.asxh", StringComparison.InvariantCultureIgnoreCase))
{
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Server);
}
}
I'm getting a lot of these error messages in my logs on one of my servers and intermittently on two others.
Googling didn't reveal very much information, mostly related to file uploads or downloads being interrupted.
My pages are basically just text files with "ok" in them that only have .aspx extension for future plans, there's no actual code powering the pages. Servers are all Windows Server 2008 RC2 x64 running IIS7 / ASP.NET 4.
Statistically it's happening well under 1% of the time but because of the volume of traffic that still clutters my event log with 2 or 3 of these messages per minute.
Edit:
I tracked down the problem, setting buffering to true stopped it occurring.
I know this has been answered, but on the off chance this helps someone else, it happened in my MVC project sometimes when I had one dbContext set at the top of a repository. When I switched to a using statement for database connections, the error never appeared again.
So, I went from this at the top of each repository:
DbContext db = new DbContext();
To this for each individual connection:
using (DbContext db = new DbContext())
{
//db connection stuff here....
}
Worth saying that no one ever reported seeing the error and no error was ever shown to the browser, but nice to get it off the logs all the same!
Are you returning a Stream?
You might need to close it after the method finishes.
Check out this: Closing Returned Streams in WCF
Here is the code this blog suggests:
public Stream GetFile(string path)
{
Stream fileStream = null;
try
{
fileStream = File.OpenRead(path);
}
catch(Exception)
{
return null;
}
OperationContext clientContext = OperationContext.Current;
clientContext.OperationCompleted +=
new EventHandler(delegate(object sender, EventArgs args)
{
if (fileStream != null) fileStream.Dispose();
});
return fileStream;
}