服务器关闭时是否可以呈现视图

时间:2013-07-22 07:44:47

标签: c# asp.net-mvc-4

我必须在服务器关闭时呈现一个简单的视图。有一个全局过滤器,用于检查服务器连接。在过滤器内部,应执行重定向以在服务器显示时显示视图。 问题是从不发生重定向到控制器。过滤器内的代码执行了几次,然后我在浏览器中收到太多的请求错误。 如果我重定向到图像或文本一切都很顺利。但渲染视图是不行的。

全局过滤器:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    using (var connection = new SqlConnection ConfigurationManager.ConnectionStrings["IncbbsConnection"].ToString()))
    {
        try
        { connection.Open(); }
        catch (SqlException)
        {
            // This works, the text shows:
            //var content = new ContentResult {Content = "Server down!", ContentType = "text/plain"};
            // filterContext.Result = content;

            // This works, the image appears:
            //filterContext.Result = new RedirectResult("~/Content/images/LoginLogo1.png");

            // doesn't perform redirect to a controller  
            filterContext.Result = new RedirectToRouteResult("ServerDown",new RouteValueDictionary(new controller = "Error", action = "ServerDownView"}));
        }

        finally
        { connection.Close(); }
    }
}

2 个答案:

答案 0 :(得分:4)

由于您的过滤器被多次执行,直到您收到太多请求错误,因此问题可能出在您注册过滤器的方式上。

使用以下方法全局应用过滤器:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new <YourFilter>);
}

但是,这也意味着您的过滤器已应用于Error控制器。您的Error控制器将检测到您的服务器已关闭,然后重定向到自身。

您可以通过检查过滤器中的控制器来避免这种情况:

if (filterContext.Controller is ErrorController)
{
    return;
}

这样,如果您已经在ErrorController

,则不会重定向

我想指出的另一件事是,以这种方式使用ActionFilter可能不是最佳解决方案。我认为您希望您的服务器大多数时间都在线。但是,此代码将在每个操作上运行。您可以实施ExceptionFilter,而不是使用ActionFilter。该过滤器仅在实际发生的情况下运行。在您的例外过滤器中,您可以检查异常的原因,以及检测到服务器是否已重定向到您的Error控制器。

更新

在对如何排除全局过滤器进行一些研究之后,我发现了这篇博文:Conditional Filters in ASP.NET MVC 3

Phil Haack介绍了如何在IFilterProvider控制器上添加不会返回过滤器的自定义Error。这是一个非常好的实现,您可以控制过滤器是否适用于实际过滤器之外。

答案 1 :(得分:0)

这不是问题的所在吗?

filterContext.Result = new RedirectToRouteResult("ServerDown",new RouteValueDictionary(new controller = "Error", action = "ServerDownView"}));

尝试将其更改为:

filterContext.Result = new RedirectToRouteResult("ServerDown",
   new RouteValueDictionary(
   new 
   {
       controller = "Error", 
       action = "ServerDownView"
   })
);

据我所知,你错过了{开始标记。


如果不是,那是否是路由问题。

RedirectToRouteResult构造函数有多个重载,你选择的那个,你在RouteName中添加,这意味着,该路由必须存在。

http://msdn.microsoft.com/en-us/library/dd493020(v=vs.108).aspx

如果是这个问题,只需删除路径名称:

filterContext.Result = new RedirectToRouteResult(
   new RouteValueDictionary(
   new 
   {
       controller = "Error", 
       action = "ServerDownView"
   })
);