19. januar 2006 - 09:51Der er
19 kommentarer og 1 løsning
Hive DataSource ud af kontrol
Hejsa
Jeg har en ascx-control med et GridView i, der bliver DataBind'et i en metode der kaldes ved en OnClick på en knap. Efter dette postback er færdigt skal man klikke på endnu en knap, og køre en metode, hvori jeg skal bruge den DataTable som jeg har DataBind'et mit GridView med. Hvordan kan jeg få fat i den? Jeg har prøvet lidt med ViewState, men jeg kan ikke rigtig få noget ud af den. Jeg har også prøvet at gemme i min HttpContext, men det hjælper heller ikke. Nogen ideer?
Session er måske lige i overkanten. Jeg skal ikke skifte mellem flere sider eller noget, det hele forgår i min UserControl.
Jeg kan ikke hente den igen, da det er en jeg selv har instantieret og smidt data i... Hvordan er det helt præcist jeg finder min kontrols ViewState. Jeg har prøvet det her, men det giver 'null':
du kan ikke trække din datakilde ud af viewstate, og hvis ud eksplicit gemmer den i viewstate selv, får du dine data lagt der 2 gange - så det kan ikke anbefales. mvh
du kan lægge dine data i Cache (er fælles for alle brugere, og giver mulighed for at sætte expiration mv). I Application (fælles for alle brugere, men uden yderligere muligheder end dem du selv skaber). I Session (specifik for en bruger, og uden særlige muligheder). I ViewState (specifik for det enkelte response, men dyrt både for processor og båndbredde). Desuden kan du self. benytte dig af cookies og querystring, og hvis du benytter version 2.0 har du nogle muligheder på profilen. men som jeg forstår dit scenarie vil jeg anbefale dig enten at hente dine data når du skal bruge dem - eller lægge dem i en variabel i session. om du gør det ene eller det andet må være en afvejning af hvor meget det fylder, kontra hvor lang tid det tager at hente. mvh
ok, jeg har prøvet at fyre det i en session, men det virker ikke. Jeg gemmer den således: Session["FormData"] = Formdata;
og henter: FormData f = (FormData)Session["FormData"];
men jeg får en uhåndteret exception.
An error was encountered while calling OnStartPage in ASP compatibility mode.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: An error was encountered while calling OnStartPage in ASP compatibility mode.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[HttpException (0x80004005): An error was encountered while calling OnStartPage in ASP compatibility mode.] System.Web.Util.AspCompatApplicationStep.OnPageStartSessionObjects() +780618 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1996
argh, det kan man ikke i UserControls, og den side jeg har min usercontrol på er en del af et større system, så det er ikke rigtig muligt at ændre så meget..
Hvad er mulighederne for at gemme data i Context.Items? Kan man godt have dem liggende der mellem 2 metoder?
ok - så er det vel bare at hente data når du har behov for dem vil jeg tro.... det er sjældent et hit at proppe det i viewstate (der kommer normalt rigeligt deri i forvejen ;o) mvh
Men problemet er jo at jeg har brug for dem 2 gange. Når man har indtastet en masse ting skal der vises en side med alle data på, hvor man skal klikke "Godkend", og så skal det hele gemmes. Derfor synes jeg det var smart at gemme det hele i en DataTable (FormData nedarver fra DataTable) så jeg dels kunne DataBind'e med den når man skal godkende data, og dels ville have nemt ved at gemme data'ene bagefter.
ja - den er jeg med på... men jeg er ikke helt med på hvad du spørger om nu.
du kan enten gemme dine data i applikationen eller lade være. der er fordele og ulemper ved begge dele, og hvis du ikke har nogen god mulighed for at gemme det i applikationen, må du jo bare hente det fra databasen hver gang.
det er ligesom når du har slået viewstate til, og i page_load skriver:
if(!IsPostBack) { someGrid.DataSource = GetData(); // henter data fra basen someGrid.DataBind(); }
eller slår viewstate fra og i page_load skriver:
someGrid.DataSource = GetData(); // henter data fra basen someGrid.DataBind();
det ene koster fordi du henter data op fra databasen hver gang... det andet koster fordi viewstate er dyrt.
det man kan sige er - at når du nu skal videre til en anden side - som også skal bruge samme data... så kunne det jo være smart at den side ikke også skulle hente de samme data, men det kan du godt fikse.
// en løsning hvor du bruger viewstate private DataTable _data;
public DataTable Data { get { return _data; } }
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { _data = new DataTable(); _data.Columns.Add("SomeText", typeof(string)); _data.Rows.Add("Hej"); _data.Rows.Add("med"); _data.Rows.Add("dig"); _data.Rows.Add("du");
// gem data i viestate grid.DataSource = ViewState["_pageData"] = _data ; grid.DataBind(); } }
protected void btnMoveOn_Click(object sender, EventArgs e) { // hent data fra viewstate _data = ViewState["_pageData"] as DataTable;
// her gør du så noget noget ved iht. det som brugeren har indtastet // ... hvad der nu skal gøres ...
// og en transfer til anden side Server.Transfer("Reciever.aspx"); }
og hvis vi siger at den side du har lavet en transfer fra hedder Sender, kan du på den side du så laver en transfer til gøre sådan noget her:
if (!IsPostBack) { Sender page = Context.Handler as Sender; GridView grid = new GridView(); grid.DataSource = page.Data; grid.DataBind(); form1.Controls.Add(grid); }
Hvis du vil spare på dit viewstate istedet - kan du så hente ved hvert request:
// en løsning hvor du ikke bruger viewstate private DataTable _data;
protected void btnMoveOn_Click(object sender, EventArgs e) { // her gør du så noget noget ved iht. det som brugeren har indtastet // ... hvad der nu skal gøres ...
// og en transfer til anden side Server.Transfer("Reciever.aspx"); }
desuden har du self. også muligheden for at
protected void btnMoveOn_Click(object sender, EventArgs e) { // gør hvad du skal med data Response.Redirect("..."); }
hvorefter du så må hente data op fra basen igen på den siden der så diregeres til.
hvis du ikke har mulighed for at gemme det i session (og ikke gider at lave håndtering af brugere i hhv. cache eller application) - kan du jo prøve begge ovenstående modeller og se hvad der er værst.
kommer din side f.eks.: til at fylde et par megabyte pga. et kæmpe viewstate, er det nok at foretrække at du suger det i basen hver gang, og hvis det tager 100 år at hente det fra basen pga. komplicerede joins mellem kæmpe tabeller uden index ell. kan det ende med at viewstate er den løsning der vil virke bedst i praksis.
Tja, det du viser virker sådan set, jeg kan bare ikke bruge det, da det system jeg udvikler til ikke er så godt til at huske ViewState. Men smid et svar, du har fortjent det ;-)
Øhm, nej det er det ikke, men det er alligevel som om dit eksempel virker udenfor systemet, men ikke inde i det.. Hmm.. Jeg ved faktisk ikke helt hvad det er der foregår, men det vil jeg da undesøge ;-)
Synes godt om
Ny brugerNybegynder
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.