繁体   English   中英

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

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

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

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

在问题上花了两天后,我发现:

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

这很有效,因为ExecuteURL会导致重写而不是重定向。 我不需要以任何方式劫持标准文件,当文件丢失时,我可以执行我的代码(将其放在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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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