我们的 ASP.NET MVC 应用程序允许经过身份验证的用户管理一个或多个链接到其帐户的“站点”。
我们的网址是 高度 可以猜测,因为我们在 URL 中使用站点友好名称而不是 Id,例如:
/sites/mysite/
/sites/mysite/settings
/sites/mysite/blog/posts
/sites/mysite/pages/create
如您所见,我们需要在多个路由中访问站点名称。
我们需要对所有这些操作执行相同的行为:
当前帐户始终可以通过 ISiteContext 对象提供给我们。以下是我如何使用普通路由参数并直接在我的操作中执行查询来实现上述所有目标:
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。
我对自定义模型活页夹做的不多,所以我想知道这是否是一份更适合他们的工作。一个关键要求是我可以将我的依赖项注入(inject)模型绑定(bind)器(对于 ISiteContext 和 IRepository - 如果需要,我可以回退到 DependencyResolver)。
非常感谢,
本
更新
下面是使用自定义模型绑定(bind)器和操作过滤器的工作代码。我仍然不确定我对此有何感想,因为
模型粘合剂:
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;
}
Action 过滤器:
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);
}
}
Controller Action :
[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);
}
最佳答案
这个绝对听起来像是 Action 过滤器的工作。您可以使用 Action 过滤器进行 DI,这不是问题。
所以,是的,只需将您现有的功能转换为 Action 过滤器,然后将其应用于每个 Action 或 Controller 或您继承的基本 Controller 。
我不太清楚您的网站是如何工作的,但您可以使用全局操作过滤器来检查特定路由值的存在,例如'站点名称'。如果存在该路由值,则意味着您需要检查该站点是否存在...
关于asp.net-mvc - 路由参数、自定义模型绑定(bind)器或操作过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6113303/