我正在尝试创建一个全局过滤器,该过滤器将针对用户登录时的每个操作运行。根据我的阅读,有两个必要的步骤。首先,在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();
}
}
然后我必须在filters文件夹中创建过滤器。
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);
}
}
我该如何使这项工作?有没有更好的办法?我可以将它添加到所有控制器,它可以工作,这不太理想。
答案 0 :(得分:5)
我有同样的经历。您可以构建一个BaseController类并将过滤器定义放入其中。然后,所有控制器必须从BaseController类继承。因此,您不必在所有控制器中使用过滤器类。
类似的东西:
public class BaseController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
...
}
}
在控制器中:
public class SampleController : BaseController
{
...
}
答案 1 :(得分: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
}
答案 2 :(得分: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);
}
首先,我建议您将此渲染一次作为功能的证明,然后我建议您将其作为定期调用。
How to constantly check for new message with setInterval without constantly notifying user?
这个堆栈线程进入如何使Ajax调用按时间间隔重复。
答案 3 :(得分:0)
一种可能的方法是使用小视图和SignalR进行推送通知。