2016-04-22 11 views
5

Ich benutze ASP.NET MVC CORE. Ich habe meinen eigenen ViewLocationExpander implementiert, damit ich mein Projekt so strukturieren kann, wie ich es möchte, und meine Ansichten dort platzieren, wo ich es möchte.Was ist IViewLocationExpander.PopulateValues ​​() für in Asp.Net Core MVC

Dies wird durch die Implementierung einer Klasse erreicht, die von IViewLocationExpander erbt und die meiste Arbeit geschieht in der folgenden Methode:

ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) 

Alles funktioniert ziemlich süß, aber die Schnittstelle definiert eine zweite Methode, die ich nicht tun wissen, wie man richtig implementieren:

PopulateValues(ViewLocationExpanderContext context) 

ich habe Artikel alle über das Internet über diese Schnittstelle gelesen, aber niemand hat wirklich viele Informationen zur Verfügung gestellt, was genau diese Methode für andere ist, als zu sagen vagee Dinge darüber, wie es hilft w i Caching.

Ich würde es wirklich schätzen, wenn jemand erklären könnte, wie diese Methode von dem Framework verwendet wird und wie ich es in geeigneter Weise verwenden kann, um das Caching zu unterstützen, wenn das tatsächlich der Fall ist.

Antwort

4

Vielleicht ist die folgende zusätzliche Informationen direkt von einem GitHub MVC issue genommen kann Ihre Frage beantworten:

Caching beinhaltet das Values Wörterbuch in seiner Lookup . Wenn die PopulateValues()-Methode keine eindeutigen Informationen zu ViewLocationExpanderContext.Values hinzufügt, wird die ExpandViewLocations()-Methode nur einmal pro ursprünglichen Dateinamen aufgerufen, d. H. Die anfängliche Information wird von da an zwischengespeichert.

Obendrein kann das spezielle Beispiel gestellt von OP helfen noch besser zu verstehen, zumindest das ist, was mir passiert ist:

  • Sein Projekt hat Ansichten mit demselben Namen unter zwei verschiedenen Verzeichnis Bäume (etwa Foo und Bar)
  • Je nach einigen durch aktuelle Aktion Kontext extrahierten Daten, die Ansicht sollte zu finden unter entweder einer dieser Bäume

Ohne Code in PopulateValues() fragt die Suchmaschine einmal an, um die Ansicht zu lokalisieren, und dann die Ansicht "Standard" -Daten (z. ControllerName, ActionName, Area usw.), um den tatsächlichen Ort, an dem die Ansicht gefunden wird, zu cachen.

Also, in OP Fall einmal eine Ansicht Lage zwischengespeichert wird (sagen wir zB aus Foo Verzeichnisbaum) jedes Mal eine Ansicht mit dem gleichen Namen ist es immer von diesem Baum sein benötigt wird, wird es keine Möglichkeit, zu erkennen, ob die einer in dem anderen Bar Baum hätte eigentlich abgeholt werden sollen. Die einzige Möglichkeit für OP besteht darin, PopulateValues() anzupassen, indem dem Verzeichnis Values spezifische, eindeutige Details hinzugefügt werden: Im aktuellen Szenario sind dies die aus dem aktuellen Aktionskontext extrahierten Informationen.

Diese zusätzlichen Informationen werden zweifach verwendet: ExpandViewLocations() könnte sie verwenden, wenn sie aufgerufen wird, um den richtigen Speicherort zu ermitteln, während die View-Engine sie zum Zwischenspeichern des einmal gefundenen Anzeigeorts verwendet.

+0

Danke! Das ist genau die Information, die ich seit über 6 Monaten lernen möchte! Diese Informationen müssen im Internet besser bekannt gemacht werden. Gut gemacht! –

+0

Dank Ihnen, wie ich auch die Möglichkeit hatte, das klar zu machen. BTW Ich stimme der Notwendigkeit zu, diesen Teil der Dokumentation zu verbessern – superjos

+1

Update: Ich bemerkte tatsächlich, dass offizielle [doc page] (https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.mvc .razor.iviewlocationexpander) ist nun aussagekräftiger: * Die aufgefüllten Werte werden verwendet, um einen Cacheschlüssel zu bestimmen - wenn alle Werte identisch mit dem letzten Aufruf von PopulateValues ​​(ViewLocationExpanderContext) sind, wird das zwischengespeicherte Ergebnis als Ansichtsort verwendet. * – superjos

2

Grundsätzlich kann das Verfahren Werte in context.Values ​​bevölkern, die später verwendet werden, um zu bestimmen, ob eine im Cache gespeicherte Liste verwendet werden soll oder wenn die ExpandViewLocations aufgerufen werden ....

+0

Können Sie das ein bisschen mehr erklären? Wenn Sie sagen "das wird später verwendet werden, um festzustellen, ob eine zwischengespeicherte Liste verwendet werden soll", wie funktioniert das? Welchen Schlüssel müsste ich in 'context.Values ​​[key]' verwenden, um einen zwischengespeicherten Wert zu verwenden? Und in welchem ​​Format müsste der Wert sein? –

3

Haben um nicht verwirrt mit ihm genug, um Ihnen eine konkrete Antwort zu geben, aber einen Blick auf IViewLocationExpander.PopulateValues(ViewLocationExpanderContext context) auf dem ASP.NET MVC GitHub Repo haben:

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 
} 

Ablesbarkeit Format:

„Ausgeführt durch a RazorViewEngine, um die Werte zu ermitteln, die von dieser Instanz von IViewLocationExpander verbraucht würden. Die berechneten Werte werden verwendet, um festzustellen, ob sich der Standort der Ansicht seit der letzten Lokalisierung geändert hat. .

Parameter:

context: Die ViewLocationExpanderContext für die aktuelle Expansionsoperation Aussichtslage“

Ich habe einen Blick auf einigen Klassen haben, die diese Schnittstelle implementieren - einige die Methode erklären, aber es lassen leer, andere setzen es

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 
} 

Der Artikel "View Location Expander in ASP.NET Core and MVC 6" ein Beispiel. Hier ein Auszug der Erklärung:

Sie können beliebig viele View Location Expander hinzufügen. IViewLocationExpander Schnittstelle hat 2 Methoden, PopulateValues und ExpandViewLocations. PopulateValues Methode können Sie Werte hinzufügen, die später von ExpandViewLocations Methode verbraucht werden können. Die Werte, die Sie in die Methode PopulateValues eingeben, werden verwendet, um den Cache-Schlüssel zu finden.ExpandViewLocations Die Methode wird nur aufgerufen, wenn kein Cache-Ergebnis für den Cacheschlüssel vorhanden ist oder wenn das Framework die Sicht im zwischengespeicherten Ergebnis nicht finden kann. In der Methode ExpandViewLocations können Sie Ihre dynamischen Ansichtsspeicherorte zurückgeben. Jetzt können Sie diese Ansicht Lage Expander in Startup.cs Datei registrieren,

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

Das ist hilfreich, aber ich verstehe immer noch nicht, was ich in "PopulateValues" implementieren sollte, wenn ich 'ExpandViewLocations' implementiert habe, um benutzerdefinierte Orte für die Suche nach Sichten bereitzustellen. Gedanken? –

+0

Ich habe mich nicht genug damit beschäftigt, Ihnen eine definitive Antwort geben zu können. Aber ich habe Ihnen Beispiele von Klassen zur Verfügung gestellt, die die Methode implementieren und nicht implementieren und einen Auszug aus einem weblogs.asp.net-Artikel beifügen. Ich denke, dass das Zusammenstellen aller Informationen einen (ungefähren) Überblick darüber gibt, wie die Dinge funktionieren. – trashr0x

+0

Ich schätze die Informationen, die Sie zur Verfügung gestellt haben, und daher die Upvote, aber letztendlich brauche ich jemanden, der diesen Teil beantwortet: Ich würde es wirklich schätzen, wenn jemand erklären könnte, wie diese Methode vom Framework verwendet wird und wie ich es entsprechend einsetzen kann darum geht es ja. –

Verwandte Themen