路线参数,自定义模型活页夹或动作过滤器?

| 我们的ASP.NET MVC应用程序允许经过身份验证的用户管理链接到其帐户的一个或多个“站点”。 我们的Urls非常容易猜测,因为我们在URL中使用的是站点友好名称,而不是ID,例如:
/sites/mysite/
/sites/mysite/settings

/sites/mysite/blog/posts
/sites/mysite/pages/create
如您所见,我们需要通过多种途径访问站点名称。 我们需要对所有这些动作执行相同的行为: 在当前帐户中查找具有给定标识符的网站 如果返回的网站为空,则返回404(或自定义视图) 如果网站不为空(有效),我们可以继续执行该操作 当前帐户始终可以通过ISiteContext对象使用。这是我可以使用普通的route参数并直接在我的操作中直接执行查询的方法来实现上述所有功能:
private readonly ISiteContext siteContext;
private readonly IRepository<Site> siteRepository;

public SitesController(ISiteContext siteContext, IRepository<Site> siteRepository)
{
    this.siteContext = siteContext;
    this.siteRepository = siteRepository;
}

[HttpGet]
public ActionResult Details(string id)
{
    var site =
        siteRepository.Get(
            s => s.Account == siteContext.Account && s.SystemName == id
        );

    if (site == null)
        return HttpNotFound();

    return Content(\"Viewing details for site \" + site.Name);
}
这还不错,但是我将需要在20种左右的操作方法上执行此操作,因此希望将其保持为DRY。 我对自定义模型活页夹没有做太多事情,所以我想知道这是否是更适合他们的工作。关键要求是我可以将我的依赖项注入到模型绑定器中(对于ISiteContext和IRepository-必要时可以依赖于DependencyResolver)。 非常感谢, 本 更新资料 以下是使用自定义模型绑定程序和动作过滤器的工作代码。我仍然不确定我对此有何看法 我应该从Modelbinder打我的数据库吗 实际上,我可以从动作过滤器中进行对象的检索和null验证。哪个更好? 模型活页夹:
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    if (!controllerContext.RouteData.Values.ContainsKey(\"siteid\"))
        return null;

    var siteId = controllerContext.RouteData.GetRequiredString(\"siteid\");

    var site =
        siteRepository.Get(
            s => s.Account == siteContext.Account && s.SystemName == siteId
        );

    return site;
}
动作过滤器:
public class ValidateSiteAttribute : ActionFilterAttribute
{       
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {           
        var site = filterContext.ActionParameters[\"site\"];

        if (site == null || site.GetType() != typeof(Site))
            filterContext.Result = new HttpNotFoundResult();

        base.OnActionExecuting(filterContext);
    }
}
控制器动作:
[HttpGet]
[ValidateSite]
public ActionResult Settings(Site site)
{
    var blog = site.GetFeature<BlogFeature>();
    var settings = settingsProvider.GetSettings<BlogSettings>(blog.Id);

    return View(settings);
}

[HttpPost]
[ValidateSite]
[UnitOfWork]
public ActionResult Settings(Site site, BlogSettings settings)
{
    if (ModelState.IsValid)
    {
        var blog = site.GetFeature<BlogFeature>();
        settingsProvider.SaveSettings(settings, blog.Id);
        return RedirectToAction(\"Settings\");
    }

    return View(settings);
}
    
已邀请:
这绝对听起来像是动作过滤器的工作。您可以使用动作过滤器进行DI没问题。 是的,只需将现有功能转换为动作过滤器,然后将其应用于您继承的每个动作或控制器或基本控制器。 我不太了解您的网站如何运作,但是您可以使用全局操作过滤器来检查特定路由值的存在,例如\'SiteName \'。如果存在该路由值,则意味着您需要继续检查该站点是否存在...     
对您的网站类型而言,自定义模型活页夹对我来说是个好主意。 您可能还需要一个动作过滤器来捕获\“ null \”并返回未找到的内容。     

要回复问题请先登录注册