当 运行 在应用程序文件夹中时,无法使自定义错误页面在 ASP.NET MVC 应用程序中工作
Cannot make custom error pages work in ASP.NET MVC application when running in application folder
我有一个 ASP.NET MVC 应用程序,它部署在 IIS 的默认网站中,并在应用程序文件夹中运行,例如http://localhost/appfolder
.
我有两个错误页面,我尝试使用 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>
以上设置有效,但如果不使用路径中的文件夹名称,我无法使其正常工作。基于 documentation,path
属性是相对于站点根目录的。
If you choose the ExecuteURL response mode, the path has to be a
server relative URL (for example, /404.htm).
因此,考虑到以上内容,以下内容应该可行,但事实并非如此。
<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>
此外,使用~/Home/NoAccess
根本不起作用,似乎IIS只是将~
放在URL中。
我的问题:是否可以在不使用应用程序文件夹名称的情况下进行上述设置?
编辑:在此片段中查看我的应用程序如何授权每个请求。
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);
}
}
它在控制器中的使用是:
[HttpGet]
[AppAutorize]
public ActionResult Item(int id)
{
Models.Home.Item model = new Models.Home.Item(id);
return View("Item", model);
}
因为您的 Web 应用程序托管在另一个网站下,错误页面的正确站点相对路径将是您所说的有效路径。我知道这不是您希望看到的,但处理此问题的最佳方法是替换 Web.Release.config
文件中的 httpErrors
元素,如下所示:
<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>
并保持标准 Web.config
路径不包括 appfolder 路径。
我倾向于如何做
我倾向于避免使用网络配置,而是将 HTTP 错误设置为以下内容:
<httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" />
然后我有一个基本控制器,我的所有控制器都继承了它,并为每个我想要自定义页面的错误代码提供了方法。所以在你的情况下:
public ViewResult NoAccess()
{
Response.StatusCode = (int) HttpStatusCode.Unauthorized;
return View("NoAccess");
}
那么在你的任何一个控制器中的使用都非常简单:
public ActionResult Test()
{
return NoAccess();
}
这将呈现您的自定义视图。这种制作错误页面的方法取决于您的用例,但这就是我设法使自定义错误页面起作用的方法。
我有一个 ASP.NET MVC 应用程序,它部署在 IIS 的默认网站中,并在应用程序文件夹中运行,例如http://localhost/appfolder
.
我有两个错误页面,我尝试使用 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>
以上设置有效,但如果不使用路径中的文件夹名称,我无法使其正常工作。基于 documentation,path
属性是相对于站点根目录的。
If you choose the ExecuteURL response mode, the path has to be a server relative URL (for example, /404.htm).
因此,考虑到以上内容,以下内容应该可行,但事实并非如此。
<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>
此外,使用~/Home/NoAccess
根本不起作用,似乎IIS只是将~
放在URL中。
我的问题:是否可以在不使用应用程序文件夹名称的情况下进行上述设置?
编辑:在此片段中查看我的应用程序如何授权每个请求。
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);
}
}
它在控制器中的使用是:
[HttpGet]
[AppAutorize]
public ActionResult Item(int id)
{
Models.Home.Item model = new Models.Home.Item(id);
return View("Item", model);
}
因为您的 Web 应用程序托管在另一个网站下,错误页面的正确站点相对路径将是您所说的有效路径。我知道这不是您希望看到的,但处理此问题的最佳方法是替换 Web.Release.config
文件中的 httpErrors
元素,如下所示:
<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>
并保持标准 Web.config
路径不包括 appfolder 路径。
我倾向于如何做
我倾向于避免使用网络配置,而是将 HTTP 错误设置为以下内容:
<httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" />
然后我有一个基本控制器,我的所有控制器都继承了它,并为每个我想要自定义页面的错误代码提供了方法。所以在你的情况下:
public ViewResult NoAccess()
{
Response.StatusCode = (int) HttpStatusCode.Unauthorized;
return View("NoAccess");
}
那么在你的任何一个控制器中的使用都非常简单:
public ActionResult Test()
{
return NoAccess();
}
这将呈现您的自定义视图。这种制作错误页面的方法取决于您的用例,但这就是我设法使自定义错误页面起作用的方法。