Avatar billede Slettet bruger
25. januar 2005 - 21:50 Der er 15 kommentarer og
1 løsning

Bevare objekt state mellem formularer

Hej gruppe,

Jeg er lige begyndt at kode lidt ASP.NET (har en lille smule Java erfaring)
og er rendt ind i et problem.

Jeg har en formular (kontakt.aspx) og en tilhørende code-behind fil.
Min formular.aspx er opdelt i to, afgrænset af en variabel, der bliver sat i
code-behindfilen, der angiver om det er formular1 eller formular2 der skal
vises.
Vil nemlig gerne have at brugeren har mulighed for at validere sine
indtastede data inden afsendelse. Så disse bliver altså vist på siden efter
brugeren har afsendt formularen første gang.

Problemet er at når brugeren sender de indtastede data anden gang - disse
sendes til en email vha. SmtpMail klassen, bliver variablene ikke medsendt i
emailen.

Det jeg har forsøgt er, at lave en klasse, der hedder Objekt_Kontakt.cs,
denne har getmetoder for alle værdierne, samt en konstruktør, der sætter
værdierne på objektet.

Jeg sætter så værdierne i den første event sådan her:

this.firmanavn = textbox_Firma.Text;
this.kontaktperson = textbox_Kontaktperson.Text;
this.adresse = textbox_Adresse.Text;
this.postnummer = textbox_Postnummer.Text;
this.by = textbox_By.Text;
this.telefon = textbox_Telefon.Text;
this.email = textbox_Email.Text;
this.ringFra = dropDown_RingesFra.SelectedValue.ToString();
this.ringTil = dropDown_RingesTil.SelectedValue.ToString();
this.ringDato = dropDown_RingesDato.SelectedValue.ToString();

og kalder opbejtet som er oprettet i toppen af klassen med
public Object_Kontakt o;

o = new Object_Kontakt(firmanavn, kontaktperson, adresse, postnummer, by,
telefon, email, ringFra, ringTil, ringDato);

Det virker fint nok med oprettelsen af objektet og jeg kan så sagtens kalde
værdierne fra samme metode, men når jeg i min mailopbygning gør fek,s.
således:

m.Body = "Firma: " + o.getFirmanavn() + "\n";
m.Body += "Kontaktperson: " + o.getKontaktperson() + "\n";

Sendes der altså ingen objektværdier med i emailen.
Jeg får en null-reference exception...

Nogen der ved hvad jeg gør galt? For burde jeg ikke kunne kalde et objekt
der lige er oprettet fra en anden metode indenfor samme klasse?

Håber nogen kan hjælpe - kunne godt tænke mig at kunne lave dette mere
objektorienteret og vil helst undgå session-variable eller hidden fields
eller hvad man ellers bruger for at overføre data mellem metoder/formularer.

Med venlig hilsen,

Thomas
Avatar billede kalp Novice
25. januar 2005 - 21:57 #1
Hvis metoderne er i samme klasse og objektet ikke er oprettet i en metode som en local variabel så kan du godt ja... men kan lige kigge din kode igennem også
Avatar billede kalp Novice
25. januar 2005 - 21:59 #2
Jeg tror det er en lokal variable.. hvis du opretter dit objekt i konstruktøren sker det ikke.. eller du kan skrive

Object_Kontakt o = new Object_Kontakt(firmanavn, kontaktperson, adresse, postnummer, by,
telefon, email, ringFra, ringTil, ringDato);

i metoden
Avatar billede kalp Novice
25. januar 2005 - 22:01 #3
Hvis jeg har forstået spørgsmålet korrekt så er det en lokal variabel for metoden så derfor kan den ikke ses i en anden metode.. hvis din metode som opretter objektet skal kalde en anden metode kan du sende det med som parameter
Avatar billede Slettet bruger
25. januar 2005 - 22:48 #4
Jeg vil meget gerne sende begge klasser hvis det vil gøre det mere tydeligt hvad det er jeg vil lave.
Kort fortalt er det jeg gør:

1. Indsamler nogle værdier fra formularen i min .aspx side

2. Sætter disse værdier lig med variable lokalt i den ene metode i min code-behind klasse.

3. Referencierer et objekt der allerede er erklæret i toppen - altså med private - hvor alle variable sendes med til en konstruktør i den anden klasse.

4. Kalder objektets metoder for at hente værdierne ind i min anden metode i min code-behind klasse.

Desværre virker det ikke som det skal, altså jeg kan se at objektet er oprettet osv., da jeg kan kalde metoderne og få udskrevet værdier fra den første metode, men ikke fra den næste - her er værdierne tilsyneladende væk.

Hvordan sørger man for at objektet lever mere end én sides "levetid"?
Avatar billede burningice Nybegynder
25. januar 2005 - 22:58 #5
du gemmer objectet i session'en, og henter det ud igen på en anden side.
Avatar billede Slettet bruger
25. januar 2005 - 23:09 #6
Jeg ville helst undgå at oprette sessionobjekter, derfor denne metode.
Vil det sige at det ikke kan gøres på andre måder end med sessionobjekter eller hidden fields i formen?
Avatar billede burningice Nybegynder
25. januar 2005 - 23:22 #7
uhm... Response.Transfer kan også gøre det, da du så på side2 kan få fat i værdierne fra side1 ved hjælp af Context.Handler
Avatar billede Slettet bruger
25. januar 2005 - 23:59 #8
Her er et svar jeg fik fra en anden gruppe vedrørende det samme problem:

"Hvis du (for skønheden i kodens skyld) vil lave det du tænker på skal du nok
arbejde med serialisering, hvor du gemmer objektet på serveren og
efterfølgende henter det frem igen. Mit gæt vil dog være at der et vist
overhead ved denne løsning, men det er ren spekulation fra min side."

Så det kan tilsyneladende godt lade sig gøre at oprette et onjekt på serveren for derefter at referere til det, det er så bare hvordan og hvad der menes med overhead...

Men hvis det er så stort et problem kan jeg selvfølgelig godt lade være med at bruge den, troede bare at det netop var muligt med objektorienterede sprog (klient-server princip eller ej).
Avatar billede burningice Nybegynder
26. januar 2005 - 00:31 #9
du skal huske på at en webside er et stateless miljø. Serveren husker ikke umiddelbart på hvad der skete på en side for 2 minutter siden. Dette kræver at man som programmør må implementere en form for state. Til det findes der Application, Session og ViewState. De to første befinder sig i serverens hukommelse og kan bruges til henholdsvis deling mellem alle sessions og indenfor den enkelte session. Ved at bruge ViewState bliver ens state gemt i tekststreng der bliver sendt med siden til klienten, og ved næste request kan man så genskabe ens state som den var sidst en side blev hentet.

Den metode du her referer til er ViewState og er fin til små mængder data der ikke er for komplekst. Og ja, der er kommer en del overhead på viewstate, og kan meget hurtigt generere en hulens masse ekstra trafik.

Jeg kan dog ikke se hvad du har imod Session. Det er en feature der er implementeret, netop for at kunne beholde sine objecter på tværs af requests. Altså i fuld tråd med OOP-principperne. At kunne bruge ViewState, men ikke session ser jeg endda endnu mere absurd.

Altså. Gem dit object i en session, og hiv det frem igen når du skal bruge. Om det er i samme request eller 9 minutter senere... doesn't matter. Det er det samme object som da du gemte det.

PS. Du kan ikke direkte sammenligne en webside med et klient-server miljø. Et et KS-miljø vil serveren som oftest huske på klienten og hvad den har foretaget sig in the past. Det gør webserveren ikke. Den modtager et request, udfører det, sender data tilbage til klienten og glemmer derefter alt om det request. Et stateless miljø.
Avatar billede burningice Nybegynder
26. januar 2005 - 00:32 #10
Cite: Så det kan tilsyneladende godt lade sig gøre at oprette et onjekt på serveren for derefter at referere til det, det er så bare hvordan og hvad der menes med overhead...

Ja, sagtens... anyone told you otherwise?
Avatar billede Slettet bruger
26. januar 2005 - 01:01 #11
Citat: Ja, sagtens... anyone told you otherwise?

Næ ikke ligefrem, men jeg er sådan set heller ikke blevet klogere på hvorfor jeg så ikke kan referere til det fra en anden metode :)
Avatar billede burningice Nybegynder
26. januar 2005 - 01:46 #12
som jeg kan se, og har forstået det... så består din side af to dele, som hver især eksisterer i to uafhængige kontekst'e, right? du har din side, lad os kalde den side/1 og side/2... samme aspx-sider men i hvert sit request.

Du opretter et object på side/1 og forventer at dette object stadigvæk findes når at du sender brugeren videre til side/2. Thats just not going to happen. Med mindre at du selv gør noget for at gemme dit state mellem dine request, så vil et object oprettet i et request ikke findes i et andet request.

Timeline:

brugeren kommer ind på din side (form1)
indstaster data i tekstboksene og submitter
du opretter et object der indeholder brugerens data
du sender brugeren videre til form2 med hans indtastede data så han kan tjekke en ekstra gang
du bruger det object du oprettede under punkt3 til at sende en email
emailen du sender indeholder ikke noget data

You see, there's something missing here. Det object du oprette under punkt 3 findes ikke under punkt 5, da vi er i to forskellige kontekst. Du bliver altså aktivt nødt til at gemme dit object så det kan tilgås på tværs af dine request's, og som sagt kan det gøres på tre forskellige måder. Application, Session eller ViewState. Personligt vil jeg gemme det i session:

Gem: Session["contact"] = o;
Hent: Object_Kontakt o = (Object_Kontakt)Session["contact"];
Avatar billede burningice Nybegynder
26. januar 2005 - 01:47 #13
it's all about context and request's :)
Avatar billede Slettet bruger
26. januar 2005 - 13:19 #14
cyberfessor, det funker jo som en drøm... Tak!
Jeg ved godt at jeg skrev at jeg helst ville undgå sessionobjekter, men der mente jeg den gængse .asp-måde, hvor man opretter et objekt for hver værdi i formularen og derefter skal trække dem ud én efter én.

Den måde du skrev er sgu god da jeg på den måde kun skal koncentrere mig om et enkelt objekt.

Skriv et svar og du skal få dine point :-)
Avatar billede burningice Nybegynder
26. januar 2005 - 13:34 #15
aah... :) ja, asp.net er lidt smartere end det ;)
Avatar billede Slettet bruger
26. januar 2005 - 13:37 #16
Hehe, ja det kan ses :-)
Glæder mig til at dykke dybere ned i det.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester