Asp.net mvc 通过多个键从存储库中绑定对象的模型

Asp.net mvc 通过多个键从存储库中绑定对象的模型,asp.net-mvc,repository,viewmodel,model-binding,Asp.net Mvc,Repository,Viewmodel,Model Binding,假设以下路线: {region}/{storehouse}/{controller}/{action} 这两个参数区域和仓库共同标识一个实体-a仓库。因此,在某个仓库的上下文中调用了一组控制器。 我想写这样的动作: public ActionResult SomeAction(Storehouse storehouse, ...) 在这里我可以读到你的想法:“写自定义模型活页夹,伙计”。我愿意。然而,问题是 如何避免自定义模型活页夹中出现魔术字符串? 这是我目前的代码: public cla

假设以下路线:

{region}/{storehouse}/{controller}/{action}
这两个参数
区域
仓库
共同标识一个实体-a
仓库
。因此,在某个仓库的上下文中调用了一组控制器。 我想写这样的动作:

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


可能还有另一种方法可以为所有操作提供
仓库
对象,即将其声明为控制器的属性,并将其填充到
控制器中。初始化

我最后使用了另一种方法。模型绑定对于我来说不是一种合适的机制。行动过滤器就是要走的路

名称与问题中的名称不同,但将场地视为仓库

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
并从站点存储库中提取对象。使用
HttpContext.Current
不太优雅,请同意。然而,一切都要经过IoC,所以测试性不会受到影响

有一个名为
ProvideCurrentSiteAttribute
的操作筛选器属性,它使用
ProvideCurrentSiteFilter
。因此,我的操作方法如下所示:

[ProvideCurrentSite]
public ActionResult Menu(Site currentSite)
{
}