0

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

全局过滤器:

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(); }
    }
}
4

2 回答 2

4

由于您的过滤器会多次执行,直到您收到太多请求错误,所以问题可能在于您如何注册过滤器。

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

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

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

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

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

这样,如果您已经在您的ErrorController.

我想指出的另一件事是,ActionFilter以这种方式使用 an 可能不是最佳解决方案。我认为您希望您的服务器大部分时间都在线。但是,此代码将在每个操作上运行。ActionFilter您可以实现ExceptionFilter而不是使用。该过滤器只会在实际发生某些事情时运行。在您的异常过滤器中,您可以检查异常的原因,如果您检测到服务器已关闭,则重定向到您的Error控制器。

更新

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

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

于 2013-07-22T09:43:08.283 回答
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"
   })
);
于 2013-07-22T09:30:10.713 回答