2016-10-10 78 views
8

我一直在将我的一些web应用整合到一个主要的ASP.NET MVC项目中;将其中的一些分配给不同的区域,以便可以通过子域访问它们。ASP.NET MVC Area可以显示自己的一组错误页面吗?

使用这个(很有用)资源(https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging),我已经设置了在Web.configcustomErrorshttpErrors,使显示的自定义错误页。效果很好。

我会为每个区域/子域使用不同的布局/样式,所以我想知道: 如何让Area显示自己的一组错误页面?

在当前的设置中,所有子域将显示主组被加入到customErrorshttpErrors切片(403.html,404.html,等等)的自定义错误的;但我宁愿为某些子域定制错误页面。 (如果地区之一只能由一个单独的域处理完全,例如,它是不实际的服务于普通的错误页面。)

更新: 下面是这种情况,与代码,请求。感谢Ben Foster,他在这里提供了很好的指导:http://benfoster.io/blog/aspnet-mvc-custom-error-pages2。我已经把customErrors的代码,但不是相应的httpErrors,为简洁起见而放弃它。

<system.web> 
    <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/500.aspx"> 
     <error statusCode="404" redirect="~/404.aspx" /> 
     <error statusCode="500" redirect="~/500.aspx" /> 
    </customErrors> 
    </system.web> 

    <location path="MyArea1"> 
    <system.web> 
     <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Areas/MyArea1/500.aspx"> 
     <error statusCode="404" redirect="~/Areas/MyArea1/404.aspx" /> 
     <error statusCode="500" redirect="~/Areas/MyArea1/500.aspx" /> 
     </customErrors> 
    </system.web> 
    </location> 

    <location path="MyArea2"> 
    <system.web> 
     <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Areas/MyArea2/500.aspx"> 
     <error statusCode="404" redirect="~/Areas/MyArea2/404.aspx" /> 
     <error statusCode="500" redirect="~/Areas/MyArea2/500.aspx" /> 
     </customErrors> 
    </system.web> 
    </location> 

上面的代码工作得很好:

  • 如果我浏览到 “example.com/does/not/exist”,我在~/404.aspx得到 预期的错误页面。
  • 如果我导航到“example.com/MyArea1/does/not/exist”,我会 得到~/Areas/MyArea1/404.aspx的自定义错误页面。

挑战:

现在我想的区域(MyArea2)要由一个完全独立的域(例如exampleOnMyOtherDomain.com)使用HostDomainConstraint(所推荐的@TetsuyaYamamoto服务,在评论下面)。通过“example.com/MyArea2/validlink”访问的链接现在将以这种方式访问​​:“exampleOnMyOtherDomain.com/validlink”。

现在,如果我尝试“exampleOnMyOtherDomain.com/does/not/exist”,我将服务于顶级404(~/404.aspx)。这可能是因为“MyArea2”不在路径中,所以路径“MyArea2”的位置不会被拾取。

我怎样才能让Area(MyArea2)服务自己的错误页面?

+1

可能的位置设置可能有所帮助,请参阅参考:https://msdn.microsoft.com/en-us/library/ms178692.aspx。它可以在每个位置的''元素中包含不同的内容,允许通过指定区域相对路径为不同的区域设置'customErrors'和'httpErrors'。 –

+0

谢谢@TetsuyaYamamoto;这是一个非常有用的评论。我尝试了'location'元素,当我的Areas是我主域的子路径(例如http://example.com/MyArea)时,'location'元素工作得很好('path =“MyArea”')!但问题在于:当我的区域完全由单独的域提供服务时,我无法使用相同的策略(例如http://myotherexample.net)。 – cyrotello

+0

访问myotherexample.net时显示什么样的错误?可能它需要在Global.asax路由模块中使用'HostNameContraint'进行额外的路由配置(也包括对该区域的URL重写)。此外,您可以编辑您的问题以包含区域和路由代码。 –

回答

6

基于一些研究,以及来自@TetsuyaYamamoto的有用指针,我采用了以下策略。

我处理“的Application_Error”事件Global.asax,使用下面的代码:

protected void Application_Error(object sender, EventArgs e) 
{ 
    string hostName = Request.Headers["host"].Split(':')[0]; 
    if (hostName.Contains("exampleOnMyOtherDomain")) 
    { 
     Exception exception = Server.GetLastError(); 
     Response.Clear(); 
     HttpException httpException = exception as HttpException; 
     Response.TrySkipIisCustomErrors = true; 

     switch (httpException.GetHttpCode()) 
     { 
      case 404: 
       Response.StatusCode = 404; 
       Server.Transfer("~/Errors/MyArea2_404.htm"); 
       break; 
      case 500: 
      default: 
       Response.StatusCode = 500; 
       Server.Transfer("~/Errors/MyArea2_500.htm"); 
       break; 
     } 
     Server.ClearError(); 
    } 
} 

注意要点:

  • hostName.Contains("exampleOnMyOtherDomain")应与地区,我比较主机名有兴趣处理。我会为其他区域添加else...if声明;
  • Response.TrySkipIisCustomErrors = true应该防止IIS试图处理错误;
  • Response.StatusCode适当设置状态码('404','500'...);
  • Server.Transfer()读入我想显示为错误页面的文件;
  • Server.ClearError()应表示错误已被处理。

我想customErrors/httpErrors继续处理常规错误。当执行通过Application_Error块而未被处理时(即未调用Server.ClearError()),customErrors/httpErrors将处理该错误。

看来,这是一个体面的策略,用于处理由不同域所服务的区域的错误。

+1

恕我直言,此策略能够实现自定义错误页面的分离域处理,但是您需要注意'TrySkipIisCustomErrors'正常工作。如果重定向到区域错误页面不起作用,请检查如果IIS已设置为集成模式,则'位于适当位置,请参阅此参考:https:// msdn.microsoft.com/en-us/library/ms690576(v=vs.90).aspx。 –

+0

会做。谢谢@TetsuyaYamamoto,感谢您的帮助! – cyrotello

相关问题