4

我正在尝试创建一个全局过滤器,如果用户登录,它将针对我拥有的每个操作运行。从我所阅读的内容来看,有两个步骤是必要的。首先,在 Global.asx 文件中添加新过滤器。

public class MvcApplication : System.Web.HttpApplication
{
    //I added this
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new NotificationFilter());
    }
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();
    }
}

然后我必须在过滤器文件夹中创建过滤器本身。

public class NotificationFilter : ActionFilterAttribute 
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    { //Breakpoint here is never triggered
        //This code doesn't work, but it's what I want to do
        if (WebSecurity.CurrentUserId > 0)
        {
            var notificationCount = db.Notifications.GroupBy(i => i.UserID).Count();
            if (notificationCount > 99)
            {
                ViewBag.Notifications = "99+";
            }
            else
            {
                ViewBag.Notifications = notificationCount;
            }
        }
        base.OnActionExecuting(filterContext);
    }
}

我怎样才能使这项工作?有没有更好的办法?我可以将它添加到所有控制器中并且它可以工作,但这并不理想。

4

4 回答 4

5

我也有同样的经历。您可以构建一个 BaseController 类并将过滤器定义放入其中。那么你所有的控制器都必须继承自 BaseController 类。因此,您不必在所有控制器中都使用过滤器类。

像这样的东西:

    public class BaseController : Controller
    {

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
         ...
         }
    }

在控制器中:

public class SampleController : BaseController
{
 ...
}
于 2013-01-26T20:01:17.743 回答
2

您可以使用此代码解决您的问题:

public class ParentController : Controller
{

   protected override void OnActionExecuting(ActionExecutingContext filterContext)
   {
       /* take current action*/
       action = (string)filterContext.RouteData.Values["action"];

       /* check if your action have your filter */
       if (!string.IsNullOrEmpty(action) && Methods.
                    Where(
                           method => method.Name == action
                           &&        method.GetCustomAttributes(typeof(/* your filter name */), true).Length > 0
                    ).Count() > 0)
          {
            // do your work    
          }


   }
}

public class YourController : ParentController 
{

  // implementation of your controller
}
于 2013-02-04T12:08:57.567 回答
1

Jed,据我了解,您希望您的所有页面都以相同的方式运行并为经过身份验证的用户呈现通知。

我建议,在您的 _layout 中,放置一个左上角的 Div 和 jquery Ajax 调用(您可以稍后将 jquery 推送到 alert.js 文件中)。

    <div id='divNotifications'></div>

    <script type="text/javascript">
       $(document).ready(function() {
       $('#divNotifications').load('Notifications/UserNotifications');
       }
    </script>

在您的通知控制器中有 UserNotifications 方法返回:

public JsonResult AjaxUserNotifications()
{

    Notifications Notifications = new GetNotifications();

    return Json(Notifications, JsonRequestBehavior.AllowGet);
}

首先,我建议您将此渲染一次作为功能证明,然后我建议您将其设为重复调用。

如何在不不断通知用户的情况下使用 setInterval 不断检查新消息?

这个堆栈线程介绍了如何使 Ajax 调用按时间间隔重复。

于 2013-01-26T23:37:31.490 回答
0

一种可能的方法是使用 little view 和 SignalR 进行推送通知。

于 2014-07-21T13:05:52.490 回答