简体   繁体   中英

Make an asp.net subapp handle file requests instead of IIS

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM