假设以下路线:
{region}/{storehouse}/{controller}/{action}
这两个参数region
和storehouse
共同标识了一个实体 - Storehouse
。因此,在一些仓库的环境中调用了一堆控制器。
我想写下这样的行动:
public ActionResult SomeAction(Storehouse storehouse, ...)
在这里,我可以阅读你的想法:“写自定义模型活页夹,男人”。我做。但问题是
如何避免自定义模型绑定器中的魔术字符串?
这是我目前的代码:
public class StorehouseModelBinder : IModelBinder
{
readonly IStorehouseRepository repository;
public StorehouseModelBinder(IStorehouseRepository repository)
{
this.repository = repository;
}
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var region = bindingContext.ValueProvider.GetValue("region").AttemptedValue;
var storehouse = bindingContext.ValueProvider.GetValue("storehouse").AttemptedValue;
return repository.GetByKey(region, storehouse);
}
}
如果只有一个密钥,则可以使用bindingContext.ModelName
...
可能还有另一种方法可以使用Storehouse
对象提供所有操作,即将其声明为控制器的属性并将其填充到Controller.Initialize
中。
答案 0 :(得分:0)
我最后采用了另一种方法。模型绑定不适合我的目的。动作过滤器是要走的路!
名称与问题中的名称不同,但将“网站”视为“仓库”。
public class ProvideCurrentSiteFilter: IActionFilter
{
readonly ISiteContext siteContext;
public ProvideCurrentSiteFilter(ISiteContext siteContext)
{
this.siteContext = siteContext;
}
void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
{
}
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.ActionParameters["currentSite"] = siteContext.CurrentSite;
}
}
ISiteContext
实现分析HttpContext.Current
并从Site Repository中提取对象。同意,使用HttpContext.Current
并不太优雅。但是,一切都通过IoC,因此可测试性不会受到影响。
有一个名为ProvideCurrentSiteAttribute
的动作过滤器属性,它使用ProvideCurrentSiteFilter
。所以,我的动作方法看起来像这样:
[ProvideCurrentSite]
public ActionResult Menu(Site currentSite)
{
}