Domanda

Si supponga che il seguente percorso:

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

Questi due parametri region e storehouse complessivamente identificare una singola entità - un Storehouse. Pertanto, un gruppo di controllori vengono chiamati nel contesto di qualche magazzino. E mi piacerebbe scrivere azioni come questa:

public ActionResult SomeAction(Storehouse storehouse, ...)

Qui posso leggere i tuoi pensieri: "Modello di scrittura personalizzati legante, l'uomo". Lo voglio. Tuttavia, la questione è

Come evitare le stringhe di magia all'interno modello personalizzato legante?
Qui è il mio codice corrente:

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);
    }
}

Se ci fosse un singolo tasto, bindingContext.ModelName potrebbe essere utilizzato ...
Probabilmente, c'è un altro modo di fornire tutte le azioni con un oggetto Storehouse, cioè dichiarando come una proprietà del controller e popolamento nel Controller.Initialize.

È stato utile?

Soluzione

Ho finito con un altro approccio. Modello vincolante non è un meccanismo appropriato per il mio scopo. Azione Filter è la strada da percorrere!

I nomi non sono gli stessi nella questione, ma Site trattare come Storehouse.

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 realizzazione analizza HttpContext.Current e tira un oggetto dal sito Repository. Utilizzando HttpContext.Current non è troppo elegante, d'accordo. Tuttavia, tutto passa attraverso CIO, quindi verificabilità non soffre.

C'è un attributo di filtro azione denominato ProvideCurrentSiteAttribute che utilizza ProvideCurrentSiteFilter. Quindi, il mio metodo d'azione che assomiglia a:

[ProvideCurrentSite]
public ActionResult Menu(Site currentSite)
{
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top