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

时间:2015-07-02 11:18:24

标签: c# asp.net iis

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

我已经尝试将应用程序池切换到经典和改变IIS和web.config中的处理程序映射,但这两种方法都没有。我还发现了有关在asp.net中制作看起来像静态文件的路线的信息,但据我所知,即使相应的文件存在,那些处理请求也是如此,所以它并不是我需要的。

1 个答案:

答案 0 :(得分:0)

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

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