Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

.Net C# page life cycle issue?

Pagina: 1
Acties:

  • maxtz0r
  • Registratie: Februari 2007
  • Laatst online: 17-12-2022
Ik loop tegen een issue aan waarvan ik mij afvraag of ik het wel goed doe gezien de situatie.

Situatie:
Er is een pagina waar een gebruiker een bestand kan uploaden doormiddel van een FileUpload. De bedoeling is echter dat er maar 1 bestand wordt geupload en dus wordt er in de PageLoad een functie aangeroepen die gaat kijken of er al een record in de database bestaat. Is dit het geval dan wordt er een methode aangeroepen die een panel terug geeft. In de Panel zit een Button en een Hyperlink. De button heeft een Delete() en gaat naar de functie waar de record uit het database wordt gedelete. De hyperlink heeft een link naar het bestand zodat het bestand kan worden bekeken.
Indien er geen record in de database is wordt de FileUpload control geladen.

Het mechanisme werkt in zoverre goed behalve dat als de button "Delete" wordt ingedrukt de pagina reload, de functie wordt aangeroepen om te kijken of er een record bestaat, deze bestaat kennelijk nog en dus wordt de panel geladen, en pas dan wordt het record pas verwijderd uit de database. Als ik namelijk in de database kijk staat het record ondertussen op delete.

De actie achter de button wordt dus kennelijk pas uitgevoerd nadat de Page_Load is gedaan, vandaar de titel.

Wat kan ik hier aan doen?

oh ps. ik heb zelf geprobeerd de functie die checkt wat er moet worden geladen in Page_init gezet, Page_Load en Page_LoadCompleted gezet maar iedere keer zelfde resultaat.

[ Voor 6% gewijzigd door maxtz0r op 16-10-2014 16:48 ]

Dying is God's way of telling you, you've been FIRED.


  • diabolofan
  • Registratie: Mei 2009
  • Laatst online: 13-11 08:57
Klopt, de Page_Load wordt eerst uitgevoerd voordat de click methode van de button wordt uitgevoerd.

Oplossing:
Check in je Page_Load methode of het een postback is (IsPostBack).
Alleen wanneer het geen postback is (dus geen click op de button) ga je controleren of er een record bestaat. Wanneer het wel een postback is doe je verder niets meer in de pageload.

Aan het einde van de Delete methode zorg je er voor dat de fileupload op visible wordt gezet.

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
PreLoad
Use this event if you need to perform processing on your page or control before the Load event.
After the Page raises this event, it loads view state for itself and all controls, and then processes any postback data included with the Request instance.
zie ook:
MSDN: ASP.NET Page Life Cycle Overview

maar persoonlijk zou ik doen wat diablofan zegt ;)

[ Voor 58% gewijzigd door BasieP op 17-10-2014 00:14 ]

This message was sent on 100% recyclable electrons.


  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 18:02
Klein stukje voorbeeld code:

C#:
1
2
3
4
5
6
7
8
9
10
11
protected void Page_Load(object sender, EventArgs e)
{
    if (Page.IsPostBack)
    {
        //doe wat je moet doen als het een PostBack is
    }
    else
    {
        //geen postback, dus toon fileupload control
    }
}

  • maxtz0r
  • Registratie: Februari 2007
  • Laatst online: 17-12-2022
diabolofan schreef op donderdag 16 oktober 2014 @ 22:53:
Klopt, de Page_Load wordt eerst uitgevoerd voordat de click methode van de button wordt uitgevoerd.

Oplossing:
Check in je Page_Load methode of het een postback is (IsPostBack).
Alleen wanneer het geen postback is (dus geen click op de button) ga je controleren of er een record bestaat. Wanneer het wel een postback is doe je verder niets meer in de postback.

Aan het einde van de Delete methode zorg je er voor dat de fileupload op visible wordt gezet.
Ok, dan is het denk ik toch handig als ik wat code plaats. Onderstaand is namelijk de situatie en kan ik volgens mij niet vanuit Delete FileUpload zichtbaar maken op de pagina.

Daarnaast zal dit ervoor zorgen(nog niet getest) dat als ik de pagina opsla, dus ik upload een bestand en klik op opslaan, dat ik FillList oversla en mijn opslaan actie dus de FileUpload control niet kan vinden? gezien deze buiten de IsPostBack staat.

uploadpagina.aspx.cs:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected void Page_Load(object sender, EventArgs e) {

    if (!Page.IsPostBack) {
        FillList();
    }
}

public void FillList() {
    //check database of antwoord bestaat:
    if (answers != null) {
        valueCell.Controls.Add(DynamicFields.CreateLiteralForUploadedItem(answers[0]));
    else {
        valueCell.Controls.Add(DynamicFields.CreateFileUpload(field, field.CssClass));
    }   
}


DynamicFields.cs:
C#:
1
2
3
4
5
6
7
8
9
10
public static Panel CreateLiteralForUploadedItem(DynamicFieldAnswer Answer) {

    //delete button:
    b.Click += (sender, e) => {
                    Answer.Delete();
    };
}
public static FileUpload CreateFileUpload(DynamicFieldInstance Field, string CssClass) {
    //create file upload
}


DynamicFieldAnswer.cs
C#:
1
2
3
4
5
public class DynamicFieldAnswer : IDataClass {
    public bool Delete() {
        return _object.Delete();
    }
}


Ik ben ondertussen nog eens aan het inlezen voor het gebruik van Dynamische Controls maar nu lees ik nog wel eens dat mensen het afraden in dit soort situaties. Vooral in verband met Page Life Cycle en dus ook dat je de dynamische controls iedere keer opnieuw moet maken anders ben je ze bij de eerste de beste postback kwijt.
Het maken van static input objecten is echter ook weer geen optie omdat zoals wellicht duidelijk het hier gaat om dynamische formulieren waar wel of niet textbox, dropdownlijstjes en/of upload controls aanwezig kunnen zijn.

Ik vermoed dus dat de methode die ik nu hanteer niet handig is maar mijn vraag is dan, want dat kan ik dan weer niet vinden, wat is dan best practices in dit geval?

[ Voor 15% gewijzigd door maxtz0r op 17-10-2014 10:42 . Reden: Extra informatie na inlezen ]

Dying is God's way of telling you, you've been FIRED.


  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
maxtz0r schreef op vrijdag 17 oktober 2014 @ 09:50:
Ik vermoed dus dat de methode die ik nu hanteer niet handig is maar mijn vraag is dan, want dat kan ik dan weer niet vinden, wat is dan best practices in dit geval?
Het ludieke antwoord daarop is: niet ASP.NET WebForms gebruiken, maar ASP.NET MVC.
Een realistischer antwoord is; ga je eens inlezen over data-bound controls, over wanneer in de lifecycle je data moet gaan binden en over hoe de data-binding pipeline automatisch naar child controls doorgezet kan worden (trickle-down).

Het is in elk geval al goed dat je naar een betere oplossing zoekt dan lappen code te gaan schrijven om toch maar te proberen de page lifecycle aan jouw applicatie te doen conformeren. Dat soort troep heb ik al iets te vaak voorbij zien komen.

  • jan-marten
  • Registratie: September 2000
  • Laatst online: 23:59
Een ander ludiek antwoord daarop is: ASP.NET page life cycle events eens door te nemen :)

  • InZane
  • Registratie: Oktober 2000
  • Laatst online: 23:48
jan-marten schreef op maandag 20 oktober 2014 @ 13:45:
Een ander ludiek antwoord daarop is: ASP.NET page life cycle events eens door te nemen :)
Ja, maar dat was al een keer gezegd:
BasieP schreef op vrijdag 17 oktober 2014 @ 00:12:
[...]

zie ook:
MSDN: ASP.NET Page Life Cycle Overview

maar persoonlijk zou ik doen wat diablofan zegt ;)
Verder vind ik de MVC tip nog niet eens zo gek.. Web Forms.. brrr :P

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 18-11 20:57
Dynamisch controls aanmaken doe je het beste in OnInit (Page_Init), als je het later doet krijg je inderdaad gezever met je Page Lifecycle. Als Page_Load niet het juiste moment is om te bepalen of je iets moet doen zou je nog kunnen kijken naar de OnLoadComplete- of OnPreRender (Page_PreRender)-events, van hieruit kun je ook nog invloed uitoefenen op het al dan niet zichtbaar zijn van bijvoorbeeld je FileUpload-control.

We are shaping the future


  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Alex) schreef op maandag 20 oktober 2014 @ 21:33:
Dynamisch controls aanmaken doe je het beste in OnInit (Page_Init), als je het later doet krijg je inderdaad gezever met je Page Lifecycle. Als Page_Load niet het juiste moment is om te bepalen of je iets moet doen zou je nog kunnen kijken naar de OnLoadComplete- of OnPreRender (Page_PreRender)-events, van hieruit kun je ook nog invloed uitoefenen op het al dan niet zichtbaar zijn van bijvoorbeeld je FileUpload-control.
Eigenlijk is het heel simpel; gewoon altijd je controls declareren.
De DataBind method van parent controls (of de page) overriden en daar de DataSource van de child controls zetten, evt afhankelijk van de waarde v/d datasource in de parent control. In de DataBind method van een control die evt. niet geoutput moet worden kun je de Visibility property zetten afhankelijk v/d waarde v/d eerder gezette datasource.

Dan één keer op niveau van de Page in Page_Load de DataSource ophalen uit een backing factory (evt. geinjecteerd via DI,), en de DataBind method aanroepen. Daarna neemt het WebForms framework zelf al de taak op zich om die aanroep naar beneden door de hele boom aan child controls te propageren.

Feitelijk bouw je dus een soort MVVM oplossing en dump je alle WebForms prut die stateful design probeert te forceren, zoals bijv. het hele 'event handler' concept. Je zult dan voor postbacks alleen wel zelf iets moeten regelen voor het parsen van form data. Misschien dat de model binding logica die met ASP.NET v4 ook voor WebForms beschikbaar is gekomen daar dan nog kan helpen.

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 18-11 20:57
Soms ontkom je er nou eenmaal niet aan om dynamisch controls aan te maken. :)

We are shaping the future


  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Alex) schreef op dinsdag 21 oktober 2014 @ 11:02:
Soms ontkom je er nou eenmaal niet aan om dynamisch controls aan te maken. :)
Je kunt er eigenlijk bijna altijd wel aan ontkomen om het daadwerkelijk aanmaken zelf te doen; laat dat alsjeblieft aan template containers over...

  • maxtz0r
  • Registratie: Februari 2007
  • Laatst online: 17-12-2022
Bedankt nog voor alle reacties. Ik zou ook graag veel liever MVC gebruiken echter is dat gewoon niet mogelijk in dit project(product bestaat al enige jaren en omzetten naar MVC zou maanden kosten).

Ik heb het uiteindelijk helemaal anders aangepakt. Er wordt nu een usercontrol geladen met zowel de FileUpload als de panel die file informatie en een delete link toont. Als er geen bestand is geupload wordt de fileupload via javascript getoond is er wel een bestand geupload wordt de fileinfo getoond. Indien er dan op delete wordt geklikt wordt file upload weer zichtbaar en fileinfo onzichtbaar en wordt er een hidden control gebruikt om bij de save actie het oude bestand te verwijderen.

Absoluut niet de schoonheidsprijs maar gezien omstandigheden(product en mijn kennis voornamelijk ;-)) beste oplossing.

Dying is God's way of telling you, you've been FIRED.

Pagina: 1