2016-04-22 24 views
5

Sto usando ASP.NET MVC CORE. Ho implementato il mio ViewLocationExpander in modo da poter strutturare il mio progetto nel modo che preferisco e posizionare le mie viste dove mi piacciono.Che cosa è IViewLocationExpander.PopulateValues ​​() per in Asp.Net Core MVC

Ciò viene realizzato mediante l'attuazione di una classe che eredita da IViewLocationExpander e la maggior parte del lavoro avviene nel seguente metodo:

ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) 

Tutto sta funzionando abbastanza dolce ma l'interfaccia definisce un secondo metodo che non lo faccio sapere come implementare correttamente:

PopulateValues(ViewLocationExpanderContext context) 

ho letto articoli in tutto internet su questa interfaccia, ma nessuno ha veramente fornito molte informazioni su cosa esattamente questo metodo è per altro che dire cose vaghe su come aiuta w con il caching.

Apprezzerei molto se qualcuno potesse spiegare come questo metodo viene utilizzato dal framework e come posso usarlo appropriatamente per aiutare il caching se è davvero quello che serve.

risposta

4

Forse le seguenti informazioni aggiuntive preso direttamente da un GitHub MVC issue può rispondere alla tua domanda:

Caching include il Values dizionario nella sua ricerca . A meno che il metodo PopulateValues() aggiunga informazioni distinte a ViewLocationExpanderContext.Values, il metodo ExpandViewLocations() verrà chiamato solo una volta per nome file originale, ad esempio le informazioni iniziali vengono memorizzate nella cache da quel momento in poi.

Oltre a questo, l'esempio particolare posto dalla OP può aiutare a capire ancora meglio, almeno questo è quello che è successo a me:

  • Il suo progetto ha una vista con lo stesso nome in due diverse directory alberi (diciamo Foo e Bar)
  • seconda alcuni dati estratti dal contesto azione corrente, al fine di individuare dovrebbero essere sotto uno di quegli alberi

Senza alcun codice in PopulateValues(), visualizzare il motore chiederà una volta per individuare la vista, quindi utilizzare la visualizzazione di dati "standard" (ad es. ControllerName, ActionName, Area, ecc.) Per memorizzare nella cache la posizione effettiva in cui è stata trovata la vista.

Quindi, nel caso in OP, una volta in una posizione vista viene memorizzata nella cache (ad esempio da dire Foo albero di directory) ogni volta una vista con lo stesso nome che è necessario sarà sempre da quell'albero, non ci sarà modo di rilevare se il uno nell'altro albero Bar avrebbe dovuto essere effettivamente prelevato.

L'unico modo per OP è quello di personalizzare PopulateValues() con l'aggiunta di particolari, distintivi vedere dettaglio a Values dizionario: nello scenario attuale, queste sono le informazioni estratte dal contesto azione corrente.

Queste informazioni aggiuntive vengono utilizzate due volte: ExpandViewLocations() potrebbero essere utilizzate quando vengono richiamate per determinare la posizione corretta, mentre il motore di visualizzazione le utilizzerà per memorizzare nella cache posizione vista una volta trovata.

+0

Grazie! Questa è esattamente l'informazione che ho voluto imparare per oltre 6 mesi! Queste informazioni devono essere meglio pubblicizzate sul web. Bel lavoro! –

+0

Grazie a voi, come ho anche avuto l'opportunità di chiarire questo punto. BTW Sono d'accordo sulla necessità di migliorare quel bit di documenti – superjos

+1

Aggiornamento: in realtà ho notato quella pagina ufficiale [doc] (https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.mvc .razor.iviewlocationexpander) è ora più descrittivo: * I valori popolati vengono utilizzati per determinare una chiave di cache: se tutti i valori sono identici all'ultima volta che è stato richiamato PopulateValues ​​(ViewLocationExpanderContext), il risultato memorizzato nella cache viene utilizzato come posizione di visualizzazione. * – superjos

2

In sostanza il metodo può compilare i valori in context.Values ​​che in seguito essere utilizzati per determinare se un elenco di cache dovrebbe essere usato o se sarà chiamato i ExpandViewLocations ....

+0

puoi spiegarlo un po 'di più? Quando dici "che verrà in seguito utilizzato per determinare se un elenco memorizzato nella cache debba essere utilizzato" come funziona? Quale chiave avrei bisogno di usare in 'context.Values ​​[chiave]' per farla usare un valore memorizzato nella cache? E in che formato dovrebbe essere il valore? –

3

Non hanno pasticciato con esso abbastanza per essere in grado di dare una risposta concreta, ma hanno uno sguardo al IViewLocationExpander.PopulateValues(ViewLocationExpanderContext context) sul repo ASP.NET MVC GitHub: formato

public interface IViewLocationExpander 
{ 
    /// <summary> 
    /// Invoked by a <see cref="RazorViewEngine"/> to determine the values that would be consumed by this instance 
    /// of <see cref="IViewLocationExpander"/>. The calculated values are used to determine if the view location 
    /// has changed since the last time it was located. 
    /// </summary> 
    /// <param name="context">The <see cref="ViewLocationExpanderContext"/> for the current view location 
    /// expansion operation.</param> 
    void PopulateValues(ViewLocationExpanderContext context); 

    // ...other method declarations omitted for brevity 
} 

Leggibilità:

"invocata da a RazorViewEngine per determinare i valori che sarebbero stati consumati da questa istanza di IViewLocationExpander. I valori calcolati vengono utilizzati per determinare se la posizione della vista è cambiata dall'ultima volta in cui è stata individuata. .

Parametri:

context: Il ViewLocationExpanderContext per l'operazione di visualizzazione posizione attuale espansione"

ho avuto uno sguardo ad alcuni classi che implementano questa interfaccia - un po 'di dichiarare il metodo, ma Leave It vuoto, altri attuarla

NonMainPageViewLocationExpander.cs:.

public void PopulateValues(ViewLocationExpanderContext context) 
{ 
} 

LanguageViewLocationExpander.cs:

private const string ValueKey = "language"; 

public void PopulateValues(ViewLocationExpanderContext context) 
{ 
    if (context == null) 
    { 
     throw new ArgumentNullException(nameof(context)); 
    } 

    // Using CurrentUICulture so it loads the locale specific resources for the views. 
#if NET451 
    context.Values[ValueKey] = Thread.CurrentThread.CurrentUICulture.Name; 
#else 
    context.Values[ValueKey] = CultureInfo.CurrentUICulture.Name; 
#endif 
} 

L'articolo "View Location Expander in ASP.NET Core and MVC 6" fornisce un esempio. Ecco un estratto della spiegazione:

È possibile aggiungere tutti gli espansori di posizione vista che si desidera. L'interfaccia IViewLocationExpander ha 2 metodi, PopulateValues e ExpandViewLocations. Il metodo PopulateValues consente di aggiungere valori che possono essere successivamente utilizzati dal metodo ExpandViewLocations. I valori inseriti nel metodo PopulateValues verranno utilizzati per trovare la chiave di cache.Il metodo ExpandViewLocations verrà richiamato solo se non vi è alcun risultato nella cache per la chiave di cache o quando il framework non è in grado di trovare la vista nel risultato memorizzato nella cache. Nel metodo ExpandViewLocations, è possibile restituire le posizioni di visualizzazione dinamica. Ora è possibile registrare questo punto di vista posizione di espansione situata Startup.cs di file,

services.Configure<RazorViewEngineOptions>(options => 
{ 
    options.ViewLocationExpanders.Add(new MyViewLocationExpander()); 
}); 
+0

Questo è utile ma continuo a non capire cosa dovrei implementare in 'PopulateValues' se ho implementato' ExpandViewLocations' per fornire posizioni personalizzate per la ricerca di viste. Pensieri? –

+0

Non ne ho mai avuto abbastanza per essere in grado di darti una risposta definitiva. Ma, vi ho fornito esempi di classi che implementano e non implementano il metodo e allegano un estratto da un articolo weblogs.asp.net. Penso che mettere insieme tutte le informazioni ti dia una visione (approssimativa) di come funzionano le cose. – trashr0x

+0

Apprezzo le informazioni che hai fornito e quindi l'upvote, ma alla fine ho bisogno di qualcuno che risponda a questa parte: mi piacerebbe davvero che qualcuno potesse spiegare come questo metodo viene usato dal framework e come posso usarlo appropriatamente per aiutare il caching se questo è davvero quello a cui serve –

Problemi correlati