Атрибут настраиваемого действия MVC - PullRequest
3 голосов
/ 21 сентября 2011

Во время тестирования (по крайней мере) мы регистрируем некоторую информацию низкого уровня для каждого контроллера / действия. Все контроллеры являются производными от нашего пользовательского BaseController, который переопределяет OnActionExecuting для ведения журналов.

У нас есть свойство в BaseController, которое определяет, будет ли эта запись в журнал, чтобы контроллер мог переопределить OnActionExecuting самостоятельно, сбросить флаг и затем вызвать "base.OnActionExecuting". Флаг обычно имеет значение true, но мы хотели бы отключить его для некоторых запросов Json, например.

Что бы мы предпочли сделать, это создать собственный контроллер / фильтр действий для обработки этого, что-то вроде этого:

[LogPageAccess(false)]
[HttpGet]
Public ActionResult Foobar()

Я уверен, что есть способ сделать это, но я не смог выяснить, как создать собственный атрибут и заставить его сбросить флаг в BaseController.

Спасибо ...

Ответы [ 2 ]

2 голосов
/ 21 сентября 2011

в моем проекте я использую следующее для проверки контроллеров доступа:

    [Capability(UserCapability.FileManagement)]
    public ActionResult FileList(FileListRequestModel request, bool ajax = false)
    {
        //code
    }

Вот мой класс возможностей

/// <summary>
/// Decorator to MVC class and method to evaluate if a certain capability is enabled
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CapabilityAttribute : AuthorizeAttribute
{
    #region Class Attributes

    private object _capability = null;

    #endregion

    #region Public Methods

    /// <summary>
    /// Create a new capability attribute
    /// </summary>
    /// <param name="capability">Context Value passed to the validator</param>
    public CapabilityAttribute(object capability)
    {
        this._capability = capability;
    }

    /// <summary>
    /// Check if attribute is enabled
    /// </summary>
    /// <param name="filterContext"></param>
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!Capability.Enabled(this._capability))
        {
            throw new UnauthorizedAccessException();
        }
        else
        {
            base.OnAuthorization(filterContext);
        }
    }

    #endregion
}

Вам просто нужно адаптировать этот код для вашего случаянадеюсь, что это станет полезным

0 голосов
/ 21 сентября 2011

Я некоторое время пытался создать простой пример вашей ситуации, но потом понял, что не могу передать данные экземпляра в Attribute - так сказать, если я установил флаг Log в false Я не мог использовать это, чтобы напрямую манипулировать свойством базового контроллера.

Проверьте это сообщение SO .

Вот код, с которым я играл (не компилируется - не может пройти this):

public class BaseController : Controller
{
    public bool LogPageRequests { get; set; }
}

public class LogPageAccess : ActionFilterAttribute
{
    public LogPageAccess(BaseController baseController, bool log = true)
    {
        baseController.LogPageRequests = log;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //Do Whatever
        base.OnActionExecuting(filterContext);
    }
}

public class SomeController : BaseController
{
    [LogPageAccess(this, false)]
    public ActionResult Index()
    {
        return View();
    }
}

Может быть, вы можете сделать что-то с помощью отражения, но может случиться так, что вам придется делать это так, как вы это делаете, поскольку кажется невозможным получить данные экземпляра для атрибута.

...