0

假设以下路线:

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

这两个参数region共同storehouse标识了一个实体 - a 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.

4

1 回答 1

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)
{
}
于 2010-04-02T08:37:49.443 回答