I wrote an asp.net app that is supposed to do nothing at all when a file matching the request url is found, but when a file is not there, it gets generated (based on certain information found in the url) and then the user is redirected to the now existing file (same url). I implemented it using Application_Error
in global.asax
and it works as intended locally, but doesn't work on remote server (where it is added as an app within an MVC application). I know the problem lies with IIS handling file requests on remote server, but I don't know how to make it not handle those. I just need the asp.net subapp to handle those file requests within it's own scope (path), but keep using IIS elsewhere (parent MVC app with the exception of subapp's path). So how do I do this (I've seen this work in another MVC app, but I'm not sure what made it work)?
I've tried switching app pool to classic and altering handler mappings in both IIS and web.config, but neither did the trick. I also found information on making routes that look like static files in asp.net, but from what I understand, those handle requests even if the corresponding file exists, so it's not quite what I need.
After spending two days on the problem I found out that:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
Should achieve the result (if I want to use Application_Error
in global.asax), but I'm guessing that the parent site needs this option to be set true too.
Since I wasn't able to make it work, I tried my luck with error handling HttpModule
, but StaticFile
handler seems to beat me to handling errors on static files, so that didn't work either.
I tried to solve this with HttpError pages
<system.webServer>
<httpErrors>
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath="" path="/Error404.aspx" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
and this works good because the ExecuteURL
causes a rewrite rather then redirect. I don't have to hijack standard file handling in any way and I can just execute my code (I put it in Page_Load
of the aspx.cs file) when the file is missing. There is one problem with this solution, it only works for a single app pool. If your subapp is running in a different app pool, using ExecuteURL
on errors inside the subapp will lead to blank 403 errors (redirecting to errors pages does works, but is not what I wanted). The idea behind the subapp was not to modify the parent site (actually sites), so this is a no go too.
In the end I wrote a handler for static files (only jpeg) and this works fine. I don't even need to set runAllManagedModulesForAllRequests
to true. My only concern is that it probably doesn't preform as well as the regular StaticFile
handler.
public class JpegHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
var url = context.Request.Url.PathAndQuery;
var path = context.Server.MapPath(url);
try
{
if (File.Exists(path) || TryRecreateFile(url)) // TryRecreateFile attempts to create the file and if it succeeds, it returns true
{
context.Response.Clear();
context.Response.ContentType = "image/jpeg";
context.Response.TransmitFile(path);
//Response.End(); // TransmitFile already Ends the response
return;
}
}
catch (Exception ex)
{
context.Response.StatusCode = 500;
Logger.LogException(ex);
return;
}
context.Response.StatusCode = 404;
}
}
In web.config:
<system.webServer>
<handlers>
<add name="jpgs" path="*.jpg" verb="GET" type="JpegHandler" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.