Laden...

ASP.Net MVC 3 und wiederwendbare Controls

Erstellt von DiViP vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.750 Views
D
DiViP Themenstarter:in
27 Beiträge seit 2009
vor 11 Jahren
ASP.Net MVC 3 und wiederwendbare Controls

Hallo,

ich habe eine Frage zu ASP.net MVC.
Es geht dabei um eine Anwendung, welche auf verschiedenen Seiten Daten in Tabellen darstellt. Da die Tabellen alle die gleiche Logik haben werden die Tabellen über einen eigenen Controller und einer View dargestellt. Über Parameter wird der Tabelle die Datenquelle und bestimmte individuelle Eigenschaften übermittelt.
Die Tabelle löst bei der Sortierung oder dem Paging einen Ajax Request aus, so dass nur Teile der Tabelle aktuallisiert werden. Der Request geht dabei direkt an den Tabellen Controller.
Da dieser dann aber die oben genannten Parameter wieder benötigt, wurden diese im TempData-Objekt gespeichert und die entsprechende ID per QueryString übergeben. So kann die Tabelle sich selbst aufrufen, ohne dabei die Datenquelle und die Eigenschaften zu verlieren.

Meine Frage ist, ob es dafür eine bessere Lösung gibt?

Denn die aktuelle Vorgehensweise ist nicht so schön, weil zum einen die TempData bis zum Ende der Session mit Daten belegt sind. Die Seiten und Tabellen sind verlinkt und der User kann hin und her wechseln, von daher ist es schwierig zu ermitteln, ab wann bestimmte Parameter nicht mehr gebraucht werden.
Bei meheren Tabellen auf einer Seite und parallelen Aufrufen der Tabellen blockiert der Controller, da immer nur ein 1 Controller gleichzeitig ausgeführt wird, aufgrund des Zugriffes auf die TempData.

Was ist die beste Lösung um in MVC eigene parametrisierte Controls zu bauen, die sich selbst aktuallisieren können ?

Für eure Hilfe wäre ich sehr Dankbar.

mit freundlichen Grüßen

16.834 Beiträge seit 2008
vor 11 Jahren

Die TempData ist nichts anderes als die Session. Hier aber Zeugs zu speichern ist nicht wirklich dolle, weil Du Probleme bekommen könntest, wenn Du mehrere Fenster offen hast.
Da sich aber die Parameter (aktuelle Seite der Tabelle, Anzahl der Elemente pro Seite) aber unterscheiden kann, sollte das definitiv nicht als irgendein Parameter hinterlegt werden; sondern lieber direkt an der Tabelle anhängen.

Dass TempData aber blockiert ist eigentlich nicht der Fall, das ist Threadsicher.
Lockst Du da irgendwas?

Ich hab für jedes meiner allgemeinen Controlls eine eigene Action,, manchmal auch eigene Area / Controller. Je nachdem wie groß das ist.
Da gibts dann auch absolut keine Probleme. Und die Parameter sind wie gesagt direkt an der Tabelle und unabhängig voneinander.

D
DiViP Themenstarter:in
27 Beiträge seit 2009
vor 11 Jahren

Vielen Dank für die Antwort.

Das Problem mit mehrfach geöffneten Fenstern/Tabs ist bekannt und auch ein Grund warum wir eine andere Lösung finden wollen.

Die TempData sind in der Session enthälten und das SessionObjekt wird im Controller automatisch gesperrt um den Zugriff zu steuern. Erklärung...
http://tech-journals.com/jonow/2011/10/22/the-downsides-of-asp-net-session-state

Wie meinst du das mit den Parametern an die Tabelle hängen?
Wenn die Tabelle sich wieder selbst aufruft, braucht diese ja die Parameter. Da die Parameter teilweise umfangreich sind und unter anderem Callbacks enthalten, können diese nicht über den QueryString übermittelt werden. Auch ein "ViewState" also die Serialisierung in einem Formfeld ist nicht möglich, da sich die Callbacks sich nicht serialisieren lassen.

Scheinbar ist unser Konzept für die Wiederwendbarkeit von Controls mit MVC so nicht möglich. Aber ich möchte auch nicht für jede Tabelle eigenen Code schreiben. Solche Redunanzen müssen doch vermeidbar sein.

mit freundlichen Grüßen

16.834 Beiträge seit 2008
vor 11 Jahren

Ich glaub aber nicht, dass das ein generelles Verhalten ist. Ich kanns kurioserweise nicht nachvollziehen, obwohl ich hier das Session-Verhalten nicht änder. Nun gut. Wird trotzdem natürlich akzeptiert.

Die Frage ist jetzt, wieso Deine Parameter-Callbacks enthalten, und wieso es nicht anders gelöst ist.
An für sich lager ich bestimmte Controls aus; verwende aber die Server-seitige Logik nicht mehrfach.

Die Tabellen sind bei mir aber an für sich immer in einer Form enthalten, sodass ich die Input-Felder (Aktuelle Seitenzahl, Filter, Elemente pro Seite..) bei entsprechenden Links / Anfragen auch verwenden kann - und die direkte Sortierung auch vom Server kommt => Reduzierung der Last.

Es ist aber absolut normal, dass Controls in MVC eigentlich immer nur das Layout betrifft. Woher die Daten - zB einer Tabelle - kommen, ist solch einem Control meist egal. Die meisten Anbieter von solchen Controls bieten hier auch nur eine JSon-Schnittstelle an, sodass alles auf dem Client gerendert wird.
Eventuell stimmt hier Deine denkweise nicht; oder Du stellst Dir derzeit etwas vor bzw. verlangst etwas, wofür das ganze hier so gar nicht gedacht ist.

Aber ganz verstanden, was Du im speziellen für Controls meinst, weiß ich nicht.
Es gibt ja neben PartialViews (mit denen man durchaus Controls umsetzen kann) auch Sections.

D
DiViP Themenstarter:in
27 Beiträge seit 2009
vor 11 Jahren

Ich habe einen Controller und eine View, welche eine Tabelle rendert. Der Callback wird aufgerufen, damit die Tabelle mit Daten gefüllt wird. Ein weiterer Callback wird z.B. aufgerufen um festzulegen, welches Script bei "Onclick" auf einer Row ausgeführt werden soll. Das ist ganze ist vergleichbar wie bei WindowsForms, wo man zum Beispiel bei einem Grid ein Event auf DrawCell hat. So dass man während die Tabelle dargestellt wird Einfluss auf die Darstellung hat.

Ich hab mal sehr vereinfacht versucht darzustellen wie das ganze aufgebaut ist.

 // IndexView
 
 var p = new Parameter();
 p.Data = (context) =>
 {
	return Load(context.Site, context.Sort, context.Filter);
 };
 p.DrawCell = (context, model) =>
 {
	return context.View.Html.ActionLink(model.Name, [Action], [Controller], new { id = model.Id} );
 };
 
 @Html.Action("Table", "Table", new { parameter = p })
 

Im TabellenController werden die Parameter in die TempData geschrieben, so dass diese verfügbar sind, wenn die TableView sich selbst aufruft.

// TableController / TableView
 
 Table.Data = parameter.Data(context);
 
@foreach(var item in Table.Data)
 ...
 <td>
	@parameter.DrawCell(context, item);
 </td>
 ...
16.834 Beiträge seit 2008
vor 11 Jahren

Ja, war mir klar, dass irgendwann ein Vergleich auf Windows Forms kommt. Du denkst aber falsch 😉
MVC hat absolut NICHTS mit Windows Forms gemeinsam; NULL! WebForms orientiert sich hier eher an Windows Forms - bei MVC musst Du dieses Denken KOMPLETT ablegen!

Was Du in MVC machen musst ist eigentlich nichts anderes, als Dass Du ein ViewModel für die Tabelle erstellst. Die View ist doof. Die Action ist intelligent.
In diesem ViewModel sind Properties enthalten, wie zB Seiten:int[], AktuelleSeite:int, ElementeProSeite:int, AktuelleElemente:object[] - (zudem sollte ein Context nicht in einer View landen; egal obs ein Datenbank-Context ist oder nicht.

Dieses ViewModel übergibst Du dann Deiner Tabelle - und die weiß überhaupt nicht, nicht mal ansatzweise, woher diese Daten überhaupt kommen. Muss sie auch nicht; sie soll sie schließlich nur anzeigen.

In einer View landet nur das Zeugs, was auch wirklich angezeigt werden soll.
Zudem weiß die View, zB welche Routen aufgerufen werden, wenn eine Aktion durchgeführt wird. Events löst man in MVC auch komplett mit jQuery; nicht mit dynamischen Callbacks - sollte man tunlichst vermeiden.

Was Du da aber machst sieht eher nach einem Zick-Zack aus.

D
DiViP Themenstarter:in
27 Beiträge seit 2009
vor 11 Jahren

Vielen Dank für die Antwort.

Ich habe mir diesbezüglich auch noch ein Buch studiert und werde nun versuchen, die Tabelle dementsprechend um zu bauen, dass es dem MVC Konzept entspricht.

In dem Buch wurde unter anderem JSON und jQuery verwendet, dass werde ich mir mal genauer anschauen müssen.

mfg