Un meilleur job mieux payé ?

Deviens chef de projet, développeur, ingénieur, informaticien

Mets à jour ton profil pro

ça m'intéresse

FAQ ASP.NET/C#Consultez toutes les FAQ

Nombre d'auteurs : 39, nombre de questions : 371, dernière mise à jour : 22 septembre 2007 

 
OuvrirSommaireWebFormsPages

On peut facilement rafraichir une page à intervale régulier grâce à du javascript. Mais quand il faut faire ça en code-behind car la fréquence de rafraichissement est variable ou dépend d'une condition, au lieu de se lancer dans des fonction javascript complexe avec une gestion de timer, il existe une fonction toute simple en ASP.NET :

 
Sélectionnez

Response.AppendHeader("Refresh", "1");
				

Le temps est exprimé en seconde et on ne peut pas utiliser d'unité de temps plus petite.

Créé le 12 octobre 2003  par David Pedehourcq

Pour vider le cache d'une page aspx il suffit d'exécuter ces quelques lignes :

 
Sélectionnez

Response.CacheControl = "no-cache";
Response.AddHeader("Pragma", "no-cache"); 
Response.ExpiresAbsolute = DateTime.Now.Date;
Response.Expires = -1;
				

ou

 
Sélectionnez

Response.Cache.SetExpires(DateTime.Now);
				

ou encore la solution html:

 
Sélectionnez

<meta http-equiv="Cache-Control" content="private"/>
<meta http-equiv="Pragma" content="no-cache"/>
				
Créé le 12 octobre 2003  par David Pedehourcq

Voyons comment on créer dynamiquement le titre d'une page : on parle ici de ce que contient la balise < title>. dans la page aspx :

 
Sélectionnez

<title id="titrePage" runat=server /> 
				

on déclare dans le code-behind :

 
Sélectionnez

protected HtmlGenericControl titrePage;
				

pour donner une valeur au titre de la page :

 
Sélectionnez

titrePage.InnerText = "FAQ ASP.NET";
				
Mis à jour le 23 mai 2005  par David Pedehourcq

Pour modifier l'entête (head) et le corps (body) d'une page, il faut leur assigner un id et définir la propriété runat à "server".

 
Sélectionnez

<head id="head" runat="server">

<body id="body" runat="server">
				

ensuite, les déclarer dans le code-behind comme étant des HtmlGenericControl, c'est à dire

 
Sélectionnez

protected HtmlGenericControl body;
protected HtmlGenericControl head;
				
 
Sélectionnez

head = Page.FindControl("head"); // on recupère le head de la page
head.InnerHtml += "Ici le texte que je peux ajouter dans le <head> de ma page";
// pareil pour le body
body = Page.FindControl("body");
body.Attributes("onclick") = "fctjavascript()"; // ici je rajoute un attribut
				
Créé le 3 octobre 2005  par David Pedehourcq

Non.

Mais pourquoi ne peut-on pas avoir plusieurs formulaires avec runat=server sur une même page ?
Il serait d'ailleurs plus judicieux de préciser qu'on ne peut pas avoir plusieurs formulaires visible sur la même page.
En effet :

 
Sélectionnez

<form id="form1" runat="server">
</form>
<form id="form2" runat="server" visible="false">
</form>

ne posera pas de problème d'exécution, tandis que :

 
Sélectionnez

<form id="form1" runat="server">
</form>
<form id="form2" runat="server">
</form>

levera l'HttpException suivante :

 
Sélectionnez

A page can have only one server-side Form tag.
				

Le modèle de programmation à formulaire unique (Single Form Model) est fait de manière à n'avoir qu'une seule balise form visible, avec l'attribut runat = server. Cela permet à ASP.NET de gérer les contrôles qui sont posés dans le formulaire, ayant la balise runat=server, coté serveur. Cela permet entre autre de pouvoir y accéder dans le code behind directement.
Le modèle de développement impose que les éléments de formulaire soient postés à la même page qui les a soumis, ce qui permet aux mécanismes d'ASP.NET (ViewState, etc ...) de fonctionner correctement.

Pour la curiosité, la pile d'appel au moment de l'exception nous permet de constater que l'exception est levée au moment de l'appel à la méthode System.Web.UI.Page.OnFormRender().

Un petit coup de reflector nous permet de voir :

 
Sélectionnez

internal void OnFormRender()
{
	if (this._fOnFormRenderCalled)
	{
		throw new HttpException(SR.GetString("Multiple_forms_not_allowed"));
	}
	this._fOnFormRenderCalled = true;
	this._inOnFormRender = true;
}

Cette méthode OnFormRender est appelée au moment du rendu du controle HtmlForm. Le code issu de Reflector nous permet bien de constater qu'un boolean est mis à vrai lors du rendu d'un controle HtmlForm. Si ce boolean est déjà à vrai, alors l'exception est levée.

Mis à jour le 20 septembre 2009  par nico-pyright(c), Didier Danse

Afin de voir comment on ajoute dynamiquement un WebControl à une page, nous allons prendre un exemple simple : ajouter un label à une page aspx.

Dans la page aspx, on ajoute un PlaceHolder :

 
Sélectionnez

<asp:PlaceHolder id="PlaceHolder1" runat="server"></asp:PlaceHolder>
				

dans le code-behind

 
Sélectionnez

protected PlaceHolder PlaceHolder1; 
private void Page_Load(System.object sender, System.EventArgs e)
{
	Label monlabel = new Label();
	PlaceHolder1.Controls.Add(monlabel);
}
				

Vous avez là le code minimal pour ajouter un contrôle dynamiquement à une page aspx. Vous pouvez ensuite jouer sur les différentes propriétés et méthodes du WebControl pour l'initialiser comme vous souhaitez.

Créé le 12 octobre 2003  par David Pedehourcq

Si l'on définit dans sa page aspx AutoEventWireup à True

 
Sélectionnez

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Default" %>

on force un mapping de certains événements de la page. Ainsi par exemple, la méthode Page_Load sera appelée après la méthode OnLoad.
Ce mapping est un confort d'utilisation pour éviter d'avoir à surcharger les méthodes de la page ; mais c'est aussi une hérésie en termes de performances. Le framework va user de reflexions et de délégates simplement pour nous éviter une surcharge.
Préferez sans hésiter les surcharges et mettez la propriété AutoEventWireup à false;

 
Sélectionnez

<%@ Page Language="C#" AutoEventWireup="fase" CodeFile="Default.aspx.cs" Inherits="Default" %>
				
protected override void OnLoad(EventArgs e)
{
	// je fais qqchose
	base.OnLoad(e);
}

au lieu de :

 
Sélectionnez

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Default" %>

protected void Page_Load(object sender, EventArgs e)
{
	// je fais qqchose
}
Créé le 14 novembre 2007  par nico-pyright(c)

Voici une petite astuce qui vous permet de positionner l'ascenceur d'une page web au niveau d'un WebControl.

Tout d'abord on crée un WebControl, un label sans texte par exemple qui sera invisible sur la page web.

Ensuite, dans votre page aspx :

 
Sélectionnez

<script> location='#<% Response.Write(varpos) %>';</script>
				



Dans le code-behind il suffit ensuite de faire :

 
Sélectionnez

public string varpos; 

varpos = "MonWebControl" ;
				

...et l'ascenceur sera possitionné au niveau du label appellé "MonWebControl".

Créé le 7 novembre 2003  par David Pedehourcq

Tout comme on l'aurait fait pour définir la page d'erreur pour toutes les pages de l'application, il faut modifier le web.config afin d'y trouver

 
Sélectionnez

<customErrors mode="On" />

Ensuite, pour la page concernée, au début du fichier .aspx,

 
Sélectionnez

<%@ Page Language="C#" ErrorPage="page.html" %> 
Créé le 4 septembre 2006  par Didier Danse

Il est nécessaire de faire "le lien" entre la page et le code-behind.

 
Sélectionnez

<body id="Body" runat="server">

et dans le code-behind:

 
Sélectionnez

Body.Style["background-color"] = "#FF0000";
Créé le 4 septembre 2006  par Didier Danse

Lien : Comment créer dynamiquement le titre de la page ?

On a parfois besoin d'envoyer des informations telles que du xml, html ou tout autre chose contenant <...>. Par défaut, ASP.NET refuse l'envoi de ces tags et l'informe par l'intermédiaire d'une exception qui signale que, par mesure de sécurité, il est interdit d'envoyer de telles choses au serveur. Effectivement, en autorisant cet envoi, il serait possible d'injecter du javascript par exemple.

Pour permettre l'envoi de ces informations, il est nécessaire de mettre validateRequest="false" dans la directive "Page".

Une fois ces informations envoyées, il faut encore préciser au serveur qu'il ne doit pas les interpréter mais bien garder cela comme du texte. Ceci se fait par l'intermédiaire de

 
Sélectionnez

string html = Server.HtmlEncode(TextBox1.Text);
				
Créé le 3 octobre 2005  par Didier Danse

Il existe une propriété qui n'est pas très connue et pourtant bien pratique pour repositionner le scroll d'une page à l'endroit où elle était avant un postback.
Il s'agit de la propriété MaintainScrollPositionOnPostback.
Imaginons une page avec beaucoup de contenu ...

 
Sélectionnez

<%@ Page MaintainScrollPositionOnPostback="true" Language="C#" AutoEventWireup="false" 
	CodeBehind="Default.aspx.cs" Inherits="testScroll._Default" %> 
		 
<!DOCTYPE html PUBLIC "-W3CDTD XHTML 1.0 TransitionalEN" "http:www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
		 
<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"> 
	<title>Untitled Page</title> 
</head> 
<body> 
	<form id="form1" runat="server"> 
		<asp:Label runat="server" Text="<%#DateTime.Now.ToShortTimeString() %>" /><br/> 
		<p> 
			ici mettre plein de trucs histoire d'avoir une barre de défilement 
		</p> 
		<br /> 
		<br /> 
		<asp:Button runat="server" Text="Valider" /> 
	</form> 
</body> 
</html> 

L'utilisation de la propriété MaintainScrollPositionOnPostback (positionnée à true) sur la page permet de rajouter automatiquement du javascript qui se chargera de re-positionner correctement le scroll à l'endroit où on l'a laissé.

Créé le 13 octobre 2008  par nico-pyright(c)

Pour que le framework.net puisse appréhender correctement le postback d'une page, il va falloir utiliser la méthode javascript _doPostBack(...).
Si on utilise une quelconque autre méthode (form.submit(), etc ...), cela ne sera pas géré correctement.
On va alors utiliser la méthode GetPostBackEventReference pour générer correctement la fonction _doPostBack.

Prenons l'exemple simpliste d'une dropdownlist qui devra poster la page à chaque changement de sélection (notez que ceci peut être fait automatiquement grâce à la propriété autopostback, mais ce n'est pas le but de la présentation).

soit la page suivante :

 
Sélectionnez

<asp:DropDownList runat="server" ID="maDropDown"> 
	<asp:ListItem Text="Valeur 1" /> 
	<asp:ListItem Text="Valeur 2" /> 
	<asp:ListItem Text="Valeur 3" /> 
</asp:DropDownList>

dans le code behind, on associe la méthode javascript onchange à la fonction qui va poster la page. On le construira ainsi :

 
Sélectionnez

protected override void OnLoad(EventArgs e) 
{ 
  maDropDown.Attributes["onchange"] = Page.ClientScript.GetPostBackEventReference(maDropDown, maDropDown.ID); 
  if (IsPostBack) 
	Response.Write("la page a été correctement postée à " + DateTime.Now.ToLongTimeString()); 
}

Vous pouvez constater que la page est postée à chaque changement de valeur dans la dropdown.
On peut également vérifier que ce postback est conforme en utilisant la propriété __EVENTTARGET comme expliqué ici.

 
Sélectionnez

protected override void OnLoad(EventArgs e) 
{ 
  maDropDown.Attributes["onchange"] = Page.ClientScript.GetPostBackEventReference(maDropDown, maDropDown.ID); 
  if (IsPostBack && Request.Form["__EVENTTARGET"] != null && Request.Form["__EVENTTARGET"].Contains(maDropDown.UniqueID)) 
  { 
	Response.Write("la page a été correctement postée par la dropdownlist à " + DateTime.Now.ToLongTimeString()); 
  } 
  base.OnLoad(e); 
}
Créé le 13 octobre 2008  par nico-pyright(c)

Prenons un exemple avec un TextBox et un bouton :

 
Sélectionnez

<asp:TextBox ID="leTextBox" runat="server" />  
<asp:Button ID="monBouton" runat="server" Text="go" OnClick="clic" /> 

on a l'événement du click dans le code behind écrit ainsi :

 
Sélectionnez

protected void clic(object sender, EventArgs e) 
{ 
	Response.Write("le bouton a été cliqué"); 
}

Comment simuler un clic par exemple lorsque la valeur du textbox change ?
Pour ca, on va utiliser la méthode GetPostBackEventReference.

 
Sélectionnez

protected override void OnLoad(EventArgs e) 
{ 
	leTextBox.Attributes["onchange"] = Page.ClientScript.GetPostBackEventReference(monBouton, monBouton.ID); 
	base.OnLoad(e); 
}

Si on s'arrete à ca, ASP.NET va nous lever une belle erreur :

 
Sélectionnez

Argument de publication ou de rappel non valide. La validation d'événement est activée via <pages enableEventValidation="true"/> 
dans la configuration ou via <%@ Page EnableEventValidation="true" %> dans une page. Pour des raisons de sécurité, 
cette fonctionnalité vérifie si les arguments des événements de publication ou de rappel proviennent du contrôle serveur qui les 
a rendus à l'origine. Si les données sont valides et attendues, utilisez la méthode ClientScriptManager.RegisterForEventValidation 
afin d'inscrire les données de publication ou de rappel pour la validation.

Cette erreur provient du fait qu'ASP.NET effectue un contrôle sur le POST pour détecter d'éventuelles attaques d'injections ou d'altération de la requete POST. C'est le principe d'event validation.
Une solution pour le désactiver est de mettre la propriété EnableEventValidation à false dans la directive de Page.
Ceci aura pour effet de désactiver complètement ce processus de validation, ce qui peut être nécessaire dans certain cas, mais ne permet plus cette vérification automatique pour toute la page (ceci ne peut pas être fait contrôle par contrôle).

L'autre solution plus propre est d'indiquer à ASP.NET que ce postpack est tout à fait autorisé. C'est ce que permet l'utilisation de la méthode RegisterForEventValidation.
Cet appel ne pourra être fait qu'en surchargeant la méthode Render de la page :

 
Sélectionnez

protected override void Render(HtmlTextWriter writer) 
{ 
	Page.ClientScript.RegisterForEventValidation(monBouton.UniqueID, monBouton.ID); 
	base.Render(writer); 
}

Désormais, le post est bien pris en compte et la méthode clic associée au bouton est bien lancée.

Créé le 13 octobre 2008  par nico-pyright(c)
  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2007 Dotnet Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.