Laden...

MVC4 - Objekte übergeben

Erstellt von Endro vor 10 Jahren Letzter Beitrag vor 10 Jahren 3.549 Views
E
Endro Themenstarter:in
96 Beiträge seit 2008
vor 10 Jahren
MVC4 - Objekte übergeben

Hallo,

suche eine Möglichkeit Objekte in MVC zu übergeben.

Ich habe Datenklassen welche mir die Daten aus der DB lesen und in einer List ablegen. Die Modelklasse besteht lediglich aus Properties.

Beim überprüfen der Berechtigung lesen ich auch noch weitere Daten aus die dann an verschiedenen Stellen gebraucht werden.

Im Controller instanziere ich dann die Datenklasse - soweit funktioniert das auch, aber wie nutze ich das Objekt auch in anderen Klassen?

Bei Desktopanwendungen übergebe ich Objekte über den Konstruktor - aber wie wird das in MVC gemacht? Muß/kann ich ViewData/ViewBag verwenden?

Könnt ihr mir sagen wie das gelöst wird, am liebsten ohne ViewData/ViewBag

Vielen Dank Endro

S
417 Beiträge seit 2008
vor 10 Jahren

Hallo,

da solltest du dir mal die Grundlagen zu Asp.net MVC durchlesen...
Zu dem Controller hast du eine View und dieser wird das jeweilige Model (oder ViewModel, wie immer du es nennen willst) zugewiesen, damit basierend darauf die Daten dargestellt werden können.

Im Controller hast du beispielsweise:

public ActionResult Edit(int id)
{
	// ...
	List<YourModel> list = ... // get entries from DB
	// ...

	return View(list);
}

Und in deiner dazugehörigen "Edit.cshtml" deklarierst du das Model mit @model und greifst später auf das typisierte Model Model zu:

@model List<NamespaceToYourModel.YourModel>

@foreach(var entry in Model)
{
	// ... html stuff
}

PS:

Bei Desktopanwendungen übergebe ich Objekte über den Konstruktor

Die Übergabe von Objekten über den Konstruktor hat absolut nichts mit dem Anwendungstyp zu tun.

E
Endro Themenstarter:in
96 Beiträge seit 2008
vor 10 Jahren

Hallo Sarc,

Danke für deine schnelle Antwort.

Aber das ist mir schon klar, verwende ich auch so.

Aber wie übergebe ich eine Instanz von einem Datenobjekt in mehreren Controllern oder evtl. an eine andere Datenklasse?

Zum Beispiel generiere ich den Benutzer beim Login, später benötige ich das Benutzerobjekt um andere Daten abhängig vom Benutzer aus der Datenbank auszulesen. Wobei das Benutzerobjekt alle wichtigen Daten enthält (die evtl. über Sessions/ViewBag oder ViewData übergeben werden könnten) besser wäre wenn ich die Daten direkt aus dem Objekt nehmen könnte.

Vielleicht ist jetzt klar was ich machen möchte - bin über jeden Tipp froh.

Endro

2.207 Beiträge seit 2011
vor 10 Jahren

Hallo Endro,

du kannst zum Beispiel einen Provider machen, der dir den user zur Verfügung stellt. Darin hast du eine Liste von Usern und lässt dir den aktuellen immer weider geben ist er nicht drin, fragst du die DB.

An die aktuelle UserId kommst du aber auch über die MembershipKlasse

Gruss

Coffeebean

S
417 Beiträge seit 2008
vor 10 Jahren

Hallo,

später benötige ich das Benutzerobjekt um andere Daten abhängig vom Benutzer aus der Datenbank auszulesen

Definiere "später". Meinst du später im gleichen Request oder meinst du in nachfolgenden Requests?
Der Controller mit dem du arbeitest wird bei jedem Request neu erzeugt, d.h. darin gespeicherte Objekte sind auch nur für den einen Request zu gebrauchen.
Du kannst dir natürlich deine Benutzerobjekte in der Session speichern (ViewBag oder ViewData machen, wie die Namen schon sagen, hier keinen Sinn).
Aber bevor du alles in der Session ablegst, lies dir erstmal die Kommentare dazu hier durch: http://stackoverflow.com/questions/4992308/asp-net-mvc-store-user-entity-in-session

Es scheint als bist du noch etwas von der Desktop-Welt geprägt. Im Web läuft einiges anders. Vor allem werden Zustände, die in Desktop-Anwendungen i.d.R. kein Problem darstellen, in Webanwendungen häufig vermieden.

16.806 Beiträge seit 2008
vor 10 Jahren

Gaaaaanz schlechte Idee, sowas in einer Session abzulegen. Warum?
Es wird hier niemals gewährleistet, dass der Nutzer die Folgeseite wirklich aufruft.

Resultat: Platzbelegung der Session innerhalb des Timeouts.
Worst Case: Server-Absturz durch Mangel der Ressourcen bei einigen hundert Usern.
Session Stealing kann man vermeiden, wenn man Sessions an den Client bindet (Security Cookie Protocol, IP-Bindung oder Two-Way-Security etc...).
Am besten ist jedoch die Verwendung von HTTPS (bereits ab 10 Dollar und sehr wenig Aufwand zu realisieren)

Im Prinzip muss bei jedem Request die Rechte überprüft werden; von einer Einmalprüfung beim Login halte ich nichts und rate dazu auch nicht.
Das AccessControl-Attribut ist hierfür die richtige Anlaufstelle; oder eben sowas wie ASP MVC4 Custom AuthorizeAttribute, wenn AllowMultiple = true ist
Je nach Loginsystem (Username, ID, Email..) kann man sich überlegen, was man als Current Identity beim Login festlegt, oder, was man zusätzlich in die Session ablegt. Es sollte aber niemals zuviel sein und lieber aus der DB laden (die hoffentlich ein gutes Schema hat).
Getreu dem Motto: lieber zwei Mal laden als unnötig Daten cachen.

Und ja: Endro, Du solltest Dir die Grundlagen von ASP.NET und ASP.NET MVC durchaus aneignen, denn das hier sind absolute Basics, die Du unbedingt beherschen musst, um nicht in 2,3 Wochen auf die Nase zu fallen.

Wie man eine MVC-Applikation aus Architektursicht aufbaut solltest Du verstanden haben, wenn Du erst mal verstanden hast, was MVC ist und wie es funktioniert. Hinzu kommt, dass Du bei Webanwendungen deutlich abstrakter und defensiver vorgehen musst als eben bei Desktop-Anwendungen.
Bei Webanwendungen musst Du beachten...
* dass sie immer mit mehreren Threads arbeitet
* dass der User auch mehrere Seiten offen haben kann - in der gleichen Session
* dass der User die URL jederzeit ändern kann und er nicht erwartet durch die Anwendung klickt
* dass der User nicht zwangsläufig auch die nächste Seite erreicht; er kann jederzeit abbrechen, ohne, dass Du dies merkst um darauf reagieren zu können
* ...

Edit: noch ein Hinweis, da keiner auf die Frage im ersten Thread eingegangen ist:
ohne Redirect hast Du keine Chance von Controller A auf Controller B bzw. dessen Actions zu navigieren.
Dies ist immer mit einer neuen Anfrage und eben dem Redirect-Result gekoppelt.

Wenn Du plötzlich den Inhalt von Action B returnen willst, dann stimmt was an Deiner Anwendungsarchitektur nicht. Dann solltest Du Dir anschauen, wie man Business-Logik auslagert und hier sauber modular vorgehen, statt mit einem "Pfusch" jetzt schon sich zu retten.
Auch hier ein Motto: eine Action liefert immer nur eine View; aber eine View darf mehrmals verwendet werden.

E
Endro Themenstarter:in
96 Beiträge seit 2008
vor 10 Jahren

Hallo,

Vielen Dank euch beiden - ja es stimmt wohl dass ich mich mehr in der Desktop-Welt Zuhause fühle.

Definition für "später": in einem der nächsten Requests

Habe mir die beiden Links mal angeschaut, bin mir aber nicht sicher ob das mein Problem betrifft - vielleicht habe ich es auch nicht richtig verstanden.

Dachte Objekte sind abhängig von der Session ... bin ich da falsch?

Das ViewBag/ViewData nicht verwendet werden können kann ich nachvollziehen
Wenn Sessions zu unsicher sind, was bleibt mir dann noch?

Die Geschichte mit dem Provider habe ich noch nicht ganz verstanden, aber könnte ich das auch für andere Datenklassen verwenden?

Sorry stelle mich echt an, aber irgendwie stellt sich gerade alles in Frage.
Gibt es keinen einfachen Weg wie man Objekte durchreichen kann?

Endro

E
Endro Themenstarter:in
96 Beiträge seit 2008
vor 10 Jahren

Hi Abt,

Vielen Dank dafür, werde es in Zukunft beachten

Wie man eine MVC-Applikation aus Architektursicht aufbaut solltest Du verstanden haben, wenn Du erst mal verstanden hast, was MVC ist und wie es funktioniert. Hinzu kommt, dass Du bei Webanwendungen deutlich abstrakter und defensiver vorgehen musst als eben bei Desktop-Anwendungen.
Bei Webanwendungen musst Du beachten...

  • dass sie immer mit mehreren Threads arbeitet
  • dass der User auch mehrere Seiten offen haben kann - in der gleichen Session
  • dass der User die URL jederzeit ändern kann und er nicht erwartet durch die Anwendung klickt
  • dass der User nicht zwangsläufig auch die nächste Seite erreicht; er kann jederzeit abbrechen, ohne, dass Du dies merkst um darauf reagieren zu können

Ja das ist mir klar - deshalb verstehe ich nicht wie Daten über mehrere Klassen ohne Sessions weitergeben kann.

Edit: noch ein Hinweis, da keiner auf die Frage im ersten Thread eingegangen ist:
ohne Redirect hast Du keine Chance von Controller A auf Controller B bzw. dessen Actions zu navigieren.
Dies ist immer mit einer neuen Anfrage und eben dem Redirect-Result gekoppelt.

Danke für die Hinweise

Endro

16.806 Beiträge seit 2008
vor 10 Jahren

Ja das ist mir klar - deshalb verstehe ich nicht wie Daten über mehrere Klassen ohne Sessions weitergeben kann.

Im Prinzip über TempData.
Du legst es in Action A in die Tempdata, leitest auf die andre Action, wo sie Du dort wieder ausliest.
TempData speichert zwar die Informationen in der Session - aber in einer kurzen Variante hiervon: nämlich nur innerhalb eines einzigen Requests.

Legst Du also in Action A etwas in TempData, dann ist es für Action B verfügbar.
In Action C ist es weg.

Schau Dir am besten mal TempData, ViewData und ViewBag an, lerne die Unterschiede und Verwendungszwecke.

E
Endro Themenstarter:in
96 Beiträge seit 2008
vor 10 Jahren

Hi,

Vielen Dank das werde ich gleich machen.

Endro

A
350 Beiträge seit 2010
vor 10 Jahren

TempData kann man aber nur nutzen, wenn man keinen Load Balancer hat.
Oder ?

S
417 Beiträge seit 2008
vor 10 Jahren

TempData kann man aber nur nutzen, wenn man keinen Load Balancer hat.
Oder ?

Wie Abt schon gesagt hat, nutzt TempData die Session (wenn auch nur für den nächsten Request), d.h. in einem Szenario in dem der Load Balancer nicht für eine Session Affinität sorgt, kann bzw. wird das schief gehen.
Aber man kann sich ja auch einen eigenen TempData-Provider bauen, der nicht auf Sessions basiert.

16.806 Beiträge seit 2008
vor 10 Jahren

Entweder man markiert Sticky Sessions, sodass sich immer die gleiche Maschine bei so etwas drum kümmert (macht man meist bei regionalen Server-Farmen) oder eben Sessions über eine andere Schicht (SQL, MongoDB.. > SessionProvider für verschiedene Varianten verfügbar).