ASP.NET MVC,"Ticket Required"属性

Cie*_*iel 6 c# asp.net-mvc castle-windsor

我正在尝试构建一个允许用户执行某些操作的系统,但是他们的帐户每次执行时都必须具有特定的"Ticket".例如,假设他们希望创建一个Product,他们需要一个CreateProductTicket.

我可以用一些'if'语句简单地做到这一点,当然,但是我想尝试一些更强大的解决方案.我的结构看起来像这样......

interface ITicket<T> where T : ITicketable
{
}
Run Code Online (Sandbox Code Playgroud)

我的基本目标是构建一个属性,可能如下所示.

public class TicketRequiredAttribute : Attribute
{
 public TicketRequiredAttribute(ITicket<T> ticket)
 {
  if(ticket == null) 
    return;
  }
}
Run Code Online (Sandbox Code Playgroud)

并且能够用此装饰Controller Repository Actions.所以......

ProductsControlller

[TicketRequired(CreateProductTicket)]
public ActionResult CreateProduct(Product product)
{
 // ... **I am unsure how to tell if TicketRequired was true or not**
}
Run Code Online (Sandbox Code Playgroud)

问题1

我不熟悉属性知道如何判断TicketRequired是否"遇到".任何人都可以启发我吗?

问题2

我遇到的问题是数据库查询.我希望能够检查用户(IMembershipRepository有一个GetUser方法),但我不完全确定如何通过属性来做到这一点.

使用Castle.Windsor,我将我的依赖注入设置为将存储库注入控制器.我想我可以通过IMembershipRepository通过TicketRequired构造函数,但我有一种感觉,就会变得很凌乱-极不稳定.有没有更合乎逻辑的方法来解决这个问题?

Oma*_*mar 6

你快到了.您可以在http://www.asp.net/mvc/tutorials/understanding-action-filters-cs找到更多详细信息.

我只会使用该操作的属性,因为该网站是我执行所有授权的地方.

这是一个可能的解决方案.我没有测试过这个,但它应该可以工作.您需要验证我重定向的方式,不确定这是否正确.

 public class TicketRequiredActionFilter : ActionFilterAttribute
 {
        private Type _ticketType;

  public TicketRequiredAttribute(Type ticketType)
  {
        _ticketRequired = ticketType;     
  }

  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
     UserServices userServices = GetUserServicesViaDIContainer(); // you'll need to figure out how to implement this 
     string userId = filterContext.HttpContext.User.Identity.Name
     bool hasTicket = userServices.HasTicket(_ticketType, (int)userId); // again, you'll need to figure out the exact implementation
     if(!hasTicket)
     {
        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Home" }, {"action", "NoPermission" } })
     }
     else
     { 
        base.OnActionExecuting(filterContext);
     }     
  }
}
Run Code Online (Sandbox Code Playgroud)

在你的控制器中:

[TicketRequiredActionFilter(typeof(CreateProductTicket))]
public ActionResult MyMethod()
{
    // do stuff as if the person is authorized and has the ticket
}
Run Code Online (Sandbox Code Playgroud)

如果用户没有票证,则重定向是问题;否则,正常继续.