Peter Bucher - Mein Experiment, meine Spielereien, meine Welt...   ·   Stefan Falz   ·   Jürgen Gutsch   ·   Golo Roden   ·   ASP.NET Zone   ·   Microsoft ASP.NET
Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

ASP.NET MVC: Daten zur View Masterpage übergeben

Ich stand gerade vor der Aufgabe, die UserTimeline eines Twitter Accounts auf einer ASP.NET MVC Masterpage anzuzeigen.
Dabei muss die Masterpage irgendwie an die Daten kommen, die sie anzeigen will.

Eine naive Suche bringt mich mit dem ersten Ergebnis sofort ans Ziel:

=> Passing Data to View Master Pages

Dort stellen sie zwei Möglichkeiten vor.
Bei der ersten wird vorgeschlagen im Konstruktor jedes Controllers die benötigten Daten in das ViewData-Dictionary zu übergeben.
Das wird natürlich mühsam und bei einer Änderung können alle Controller angefasst werden.

Die zweite Möglichkeit schlägt einen abstrakten Basiscontroller vor, in dessen Konstruktor das ViewData-Dictionary gefüllt wirde.
Eine gute Lösung und die Änderung findet an einer Stelle statt.

Alle Controller müssen dann von dem abstrakten Controller erben, dabei wird jedesmal dessen Konstruktor ausgeführt und die Daten übergeben.
Ein solcher Controller könnte bspw. so aussehen:




namespace Netkk.Controllers
{
    public abstract class ApplicationController : Controller
    {
        public ApplicationController() {
            ITwitterRepository repository = new TwitterRepository();
            IEnumerable<string> formattedTweets = repository.GetFormattedUserTimeLine(
                "username",
                "password",
                4);

            ViewData["userTimeLine"] = formattedTweets;
        }
    }
}

Und im Masterpage View kann kann über das Dictionary darüber iteriert werden:

<%
    foreach(string formattedTweet in (IEnumerable<string>)ViewData["userTimeLine"]) {
       %>
        <p>
            <%= formattedTweet %>
        </p>
       <%
   }
%>

Ist dagegen etwas auszusetzen oder gibt es eine bessere Lösung?

Veröffentlicht Samstag, 28. März 2009 00:03 von Peter Bucher

Kommentare

# re: ASP.NET MVC: Daten zur View Masterpage übergeben

Ich muss sagen, dass ich nicht so begeistert davon bin, die Daten im c'tor zu laden, hier einige Gründe:

- Wahrscheinlich werden zum Laden der Daten externe Abhängigkeiten benötigt. Verwendet man Dependency Injection, ist man gezwungen, Contructor-Injection zu verwenden. Property-Injection scheidet aus.

- Was, wenn die Daten gar nicht benögigt werden (Ajax-Actions)? Dann werden sie dennoch unnötigerweise geladen.

Mein "Gegenvorschlag":

statt in den Konstruktor des Basiskontrollers packt man den Code in OnActionExecuted - das löst schon mal das DI Problem. Zudem definiert man ein "opt-out" Attribut, dass man auf jede Action setzt, dass die Masterpagedaten nicht benötigt. OnActionExecuted kann dadurch bestimmen, wann Daten geladen werden müssen und wann nicht. Alternativ oder zusätzlich definiert man eine Methode, um das Laden auf Fallbasis in der Action deaktivieren (DisableMasterPageData()) oder ähnliches. Oder man lässt OnActionExecuted auf eine andere schlaue Art bestimmen, wann was geladen werden muss.

Grüße,

Andre

Sonntag, 29. März 2009 18:11 by Andre Loker

# re: ASP.NET MVC: Daten zur View Masterpage übergeben

Hallo Andre

Sehr guter Gegenvorschlag, gefällt mir :-)

Danke!

Montag, 30. März 2009 09:51 by Peter Bucher

# re: ASP.NET MVC: Daten zur View Masterpage übergeben

Alternativ ginge natürlich auch noch ein ActionFilter. Dadurch wird das ganze auch noch einfacher wiederverwendbar, da man nicht von einer bestimmten Klasse erben muss.

Ich habe für MonoRail etwas vergleichbares gebastelt. Es gibt dabei eine Registrierung, an der sich alles anmelden kann, was Master Page Daten (ich nenne diese daten "secondary view data" im Gegensatz zu den "primären" Daten, die angezeigt werden sollen) laden muss/kann. Der ActionFilter ruft dann alle registrierten "Datenanbieter" auf, die dann die Daten laden. Das System hat den Vorteil, dass man leicht Daten hinzufügen und wieder wegnehmen kann.

Man kann zudem die Datenanbieter kategorisieren, z.B.: "Frontpage", "Anonymous views", "Logged in views", "Ads" usw.

Z.B. kann man beschließen, angemeldeten Besuchern keine Werbung zu zeigen. Durch die Kategorisierung kann man bei Bedarf also noch weiter steuern, was geladen werden muss. Das sieht dann etwa so aus:

[SkipSecondaryViewData("Ads")]

public void EineActionFürAngemeldeteBenutzer(){

}

Eventuell ist das auch schon overkill, ich bin da selbst noch am Experimentieren.

Montag, 30. März 2009 13:44 by Andre Loker

# re: ASP.NET MVC: Daten zur View Masterpage übergeben

Bei der Lösung die ich brauchte, wollte ich die Daten immer angezeigt haben.

Allerdings hat sich dieser Umstand schon geändert, sodass ich die Daten jetzt in einer ActionMethod laden.

Aber deine Vorschläge sind echt gut. Ich muss mal damit rumspielen.

Komplexere Situationen erfordern halt auch komplexere Lösungen.

Jedoch sollte man immer die einfachste davon nehmen.

Ist halt immer ein Kampf zwischen Flexibilität und Einfachheit :)

Montag, 30. März 2009 16:12 by Peter Bucher
Anonyme Kommentare sind nicht zugelassen