简体   繁体   English

在应用程序文件夹中运行时,无法使自定义错误页面在ASP.NET MVC应用程序中工作

[英]Cannot make custom error pages work in ASP.NET MVC application when running in application folder

I have an ASP.NET MVC application, that is deployed in the Default web site in IIS and it runs inside an application folder, eg http://localhost/appfolder . 我有一个ASP.NET MVC应用程序,该应用程序部署在IIS的默认网站中,并且在应用程序文件夹(例如http://localhost/appfolder

I have two error pages and I tried to set them using the <httpErrors> section in web.config. 我有两个错误页面,我尝试使用web.config中的<httpErrors>部分进行设置。

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="401" />
    <remove statusCode="500" />
    <error statusCode="401" responseMode="ExecuteURL" path="/appfolder/Home/NoAccess" />
    <error statusCode="500" responseMode="ExecuteURL" path="/appfolder/Home/Error" />
</httpErrors>

The above setup works, but I could not make it work without using the folder name inside the paths. 上面的设置有效,但是如果不使用路径内的文件夹名称,则无法使其正常工作。 Based on the documentation the path attribute is relative to the site root. 根据文档path属性是相对于站点根目录的。

If you choose the ExecuteURL response mode, the path has to be a server relative URL (for example, /404.htm). 如果选择ExecuteURL响应模式,则该路径必须是服务器相对URL(例如/404.htm)。

So, with the above in mind, the following should work, but it doesn't. 因此,考虑到以上内容,以下内容应该有效,但事实并非如此。

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="401" />
    <remove statusCode="500" />
    <error statusCode="401" responseMode="ExecuteURL" path="/Home/NoAccess" />
    <error statusCode="500" responseMode="ExecuteURL" path="/Home/Error" />
</httpErrors>

Also, using ~/Home/NoAccess does not work at all, it seems that IIS simply puts ~ in the URL. 另外,使用~/Home/NoAccess根本不起作用,似乎IIS只是在URL中放入~

My question : Is it possible to have the above setup without having to use application folder name? 我的问题 :是否可以在不使用应用程序文件夹名称的情况下进行以上设置?

Edit : See in this snippet how my application is authorizing each request. 编辑 :在此代码段中查看我的应用程序如何授权每个请求。

public class AppAutorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool authorized = false;
        // Business logic to decide if authorized
        return authorized;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);
    }
}

And its use in a controller is: 它在控制器中的用法是:

[HttpGet]
[AppAutorize]
public ActionResult Item(int id)
{
    Models.Home.Item model = new Models.Home.Item(id);

    return View("Item", model);
}

Because your web application is hosted under another website the correct site relative path for the error pages would be the one you said works. 由于您的Web应用程序托管在另一个网站下,因此错误页面的正确站点相对路径将是您所说的有效路径。 I know this isn't what you was hoping to see but the best way of handling this is to replace that httpErrors element in the Web.Release.config file like the following: 我知道这是不是你希望看到的,但处理这个问题的最好办法是更换httpErrors中的元素Web.Release.config文件类似如下:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document Transform">
    <system.webServer>
        <httpErrors xdt:Transform="Replace">
            <remove statusCode="401" />
            <remove statusCode="500" />
            <error statusCode="401" responseMode="ExecuteURL" path="/appfolder/Home/NoAccess" />
            <error statusCode="500" responseMode="ExecuteURL" path="/appfolder/Home/Error" />
        </httpErrors>
    </system.webServer>
</configuration>

And keep the standard Web.config with the path excluding the appfolder path. 并保留标准Web.config的路径(不包含appfolder路径)。

How I tend to do it 我怎么做

I tend to shy away from using the web config and instead set the HTTP errors to the following: 我倾向于避开使用Web配置,而是将HTTP错误设置为以下内容:

<httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" />

I then have a base controller which all my controllers inherit from with methods for each error code which I want a custom page for. 然后,我有了一个基本控制器,我的所有控制器都从中继承了我想要自定义页面的每个错误代码的方法。 So in your case: 因此,在您的情况下:

public ViewResult NoAccess()
{
    Response.StatusCode = (int) HttpStatusCode.Unauthorized;

    return View("NoAccess");
}

Then the usage in any of your controllers is very simple: 然后,在任何控制器中的用法都非常简单:

public ActionResult Test()
{
    return NoAccess();
}

This will then render your custom view. 然后将呈现您的自定义视图。 This method of doing error pages depends on your use case but that's how I've managed to get custom error pages to work. 这种处理错误页面的方法取决于您的用例,但这就是我设法使自定义错误页面起作用的方式。

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

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