1) Само собой, эти самые атрибуты никто не мешает слегка параметризовать
public enum UserTypes
{
Admin = 0,
Moderator = 1,
RegisteredUser = 2,
Guest = 3
}
public sealed class AccessByTypeAttribute: ActionFilterAttribute
{
private List<UserTypes> _types;
public AccessByTypeAttribute(params UserTypes[] permissionedTypes)
{
_types = new List<UserTypes>();
_types = permissionedTypes.ToList();
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
//меняем на любой вариант получения прав текущего юзера
UserTypes currentUserType = UserTypes.Admin;
if (!_types.Contains(currentUserType))
{
throw new AccessViolationException("No way, dude!");
}
}
}
public class AdminController: Controller
{
[AccessByType(UserTypes.Admin, UserTypes.Moderator)]
public ActionResult SomeSecureAction()
{
return View();
}
}
2) Достаточно часто в некоторый обработчик передаётся Id - юзера, записи в блоге, чего угодно, и сам Action Method начинается с проверки этого id на существование. Это тоже прекрасно параметризуется:using System.Web.Mvc;
using System.Web.Routing;
public sealed class EntityExistsAttribute: ActionFilterAttribute
{
private string _typeName;
public EntityExistsAttribute(string entityType)
{
_typeName = entityType;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
//Тип для генерик-метода. К сожалению, сделать сам атрибут генериком не получится.
System.Type entity = System.Type.GetType(_typeName);
//Сам айдишник для проверки
long targetId = (long) filterContext.ActionParameters["id"];
bool neededEntityExists = (MyDbRepository.CheckExistance<entity.GetType()>(_paramId)) != null;
if (!neededEntityExists)
{
filterContext.Result =
new RedirectToRouteResult(new RouteValueDictionary
{
{"controller", "Home"},
{"action", "Error"},
{"name", "NotExists"}}
);
}
}
}
public class UserController:Controller
{
[EntityExists("User")]
public ActionResult ShowUserInfo(long id)
{
//бла-бла-бла
}
}
3) В случае необходимости применения нескольких атрибутов для метода порядок их применения можно выставить с помощью параметра Order:public class UserController:Controller
{
[AccessByType(UserTypes.Admin, Order=1)]
[EntityExists("User", Order = 2)]
public ActionResult ShowUserInfo(long id)
{
//бла-бла-бла
}
}
Комментариев нет:
Отправить комментарий