通过几个键对存储库中的对象进行模型绑定

时间:2010-02-04 13:30:14

标签: asp.net-mvc repository viewmodel model-binding

假设以下路线:

{region}/{storehouse}/{controller}/{action}

这两个参数regionstorehouse共同标识了一个实体 - 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中。

1 个答案:

答案 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)
{
}