使asp.net子应用程序处理文件请求,而不是IIS

本文关键字:IIS 请求 文件 net asp 应用程序 处理 | 更新日期: 2023-09-27 18:00:44

我写了一个asp.net应用程序,当找到与请求url匹配的文件时,该应用程序应该什么都不做,但当没有文件时,它会生成(基于url中的某些信息),然后用户被重定向到现在存在的文件(相同的url)。我在global.asax中使用Application_Error实现了它,它在本地按预期工作,但在远程服务器上不工作(它是作为MVC应用程序中的应用程序添加的)。我知道IIS在远程服务器上处理文件请求的问题,但我不知道如何让它不处理这些请求。我只需要asp.net子应用程序在它自己的范围(路径)内处理这些文件请求,但在其他地方继续使用IIS(父MVC应用程序,子应用程序的路径除外)。那么我该如何做到这一点呢(我在另一个MVC应用程序中看到过这一点,但我不确定是什么让它发挥作用)?

我尝试过将应用程序池切换为经典,并在IIS和web.config中更改处理程序映射,但都没有成功。我还在asp.net中找到了关于制作看起来像静态文件的路由的信息,但据我所知,即使存在相应的文件,这些路由也会处理请求,所以这不是我所需要的。

使asp.net子应用程序处理文件请求,而不是IIS

花了两天时间解决这个问题后,我发现:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

应该可以实现这个结果(如果我想在global.asax中使用Application_Error),但我猜父站点也需要将此选项设置为true。

由于我无法使其工作,我尝试了错误处理HttpModule,但StaticFile处理程序似乎在处理静态文件的错误方面击败了我,所以这也不起作用。

我试图用HttpError页面解决这个问题

<system.webServer>
    <httpErrors>
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" prefixLanguageFilePath="" path="/Error404.aspx" responseMode="ExecuteURL" />
    </httpErrors>
</system.webServer>

并且这工作得很好,因为CCD_ 6引起重写而不是重定向。我不必以任何方式劫持标准文件处理,当文件丢失时,我可以执行我的代码(我把它放在aspx.cs文件的Page_Load中)。这个解决方案有一个问题,它只适用于单个应用程序池。如果您的子应用程序在不同的应用程序池中运行,则在子应用程序内的错误上使用ExecuteURL将导致403个空白错误(重定向到错误页面确实有效,但不是我想要的)。子应用程序背后的想法是不修改父站点(实际上是站点),所以这也是不可行的。

最后,我为静态文件(只有jpeg)编写了一个处理程序,效果很好。我甚至不需要将runAllManagedModulesForAllRequests设置为true。我唯一担心的是,它可能没有像常规的StaticFile处理程序那样预成型。

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;
    }
}

在web.config中:

<system.webServer>
  <handlers>
    <add name="jpgs" path="*.jpg" verb="GET" type="JpegHandler" resourceType="Unspecified" preCondition="integratedMode" />
  </handlers>
</system.webServer>