cs_stailer
Messages postés507Date d'inscriptionjeudi 28 mars 2002StatutMembreDernière intervention13 mai 2009
-
19 mars 2005 à 13:11
cs_stailer
Messages postés507Date d'inscriptionjeudi 28 mars 2002StatutMembreDernière intervention13 mai 2009
-
27 mars 2005 à 14:49
Bonjour,
Je suis en train de faire plusieurs contrôles serveurs en asp.net et la
plupart ont besoin d'un fichier javascript externe pour fonctionner
ainsi qu'un CSS.
Etant donné que je veux respecter au maximum le XHTML (et que j'y
arrive : ) ) j'aimerais référencé ces fichiers externes dans le HEAD de
la page qui contient le contrôle serveur.
Alors la solution est toute simple : l'écrire soi-même... Mais bon, c'est pas très pro.
Donc vous aurez deviné ma question : Est-il possible, dans le code d'un
contrôle serveur, de lui dire d'écrire dans le HEAD qui le contient ?
jesusonline
Messages postés6814Date d'inscriptiondimanche 15 décembre 2002StatutMembreDernière intervention13 octobre 201029 19 mars 2005 à 16:16
oui, c'est possible, mais tu vas t'amuser
Pour cela il faut que tu dérives l'objet page et que tu en fasses
hériter toutes tes pages, ensuite tu overrides la méthode render, et tu
fais un peu de manipulation de string, et tu obtient ce que tu veux.
Regarde la classe de Sebmafate sur www.asp-php.net qui permet justement d'ecrire du code xhtml avec asp.net
cs_stailer
Messages postés507Date d'inscriptionjeudi 28 mars 2002StatutMembreDernière intervention13 mai 20091 19 mars 2005 à 17:31
ben justement c'est sa classe (que j'ai un peu modifié) que j'utilise dans mon appli...
Mais moi j'aurai préféré que ce soit au niveau du contrôle serveur
lui-même concernant le référencement des fichiers .Js et .Css.
En fait ce sont surtout les css qui posent souci... car même si on mes
les Js dans le body ca marche et ca respecte le XHTML. il aurait fallu
que les composants posés sur les webforms génère ce texte (par exemple)
dans le head :
jesusonline
Messages postés6814Date d'inscriptiondimanche 15 décembre 2002StatutMembreDernière intervention13 octobre 201029 19 mars 2005 à 17:42
moi aussi j'ai pas mal modifié sa classe car j'ai trouvé quelques bugs
:p (je lui ai dit, et il mettra surement à jour la source la bas)
Sinon ce que je ferais c'est assez simple, j'overriderais la fonction
RegisterStartupScript de la classe Usercontrol, je ferais toutes les
modifs la dedans, pour ecrire dans le head de la page, et ensuite
j'ajouterais mes scripts ou css via registerstartupscript.
Pour pouvoir écrire dans le head à parti de userControl, il faut
rajouter une méthode dans la classe XHTMLPage qui prend en paramètre,
un ID (par exemple) et le code a rajouter ...
dans le userControl pour écrire tu n'auras qu'a faire un truc du genre
ctype(me.page,xhtmlpage).AddFonction ...
Sinon une méthode plus simple, mais plus "crade" est de rajouter ton
CSS via un script JS ... mais bon c'est pas bien, on garde certes la
validation du xhtml mais il n'a pas été pensé dans ce but.
cs_stailer
Messages postés507Date d'inscriptionjeudi 28 mars 2002StatutMembreDernière intervention13 mai 20091 20 mars 2005 à 19:34
Ben je pense comprendre la classe que j'ai dérivé puisque je m'en sers
partout dans mon appli et je pense comprendre les usercontrol puisque
j'en ai fait plusieurs... C'est donc ta "méthodologie" qui reste
évasive.
J'ai bien rajouter la méthode comme tu as dit dans la classe XHTMLPage
et j'ai bien fait la conversion de type (en C# par contre) comme
ceci :
(this.Page.Parent as XHTMLPage).AjouteDansHead("texte à ajouter");
Donc j'ai bien tout suivi à la lettre mais ca me dit que la cast n'est
pas valide... J'ai essayé avec this.Page ou this.Parent ou
this.Parent.Page, mais ca revient au même.
cs_stailer
Messages postés507Date d'inscriptionjeudi 28 mars 2002StatutMembreDernière intervention13 mai 20091 20 mars 2005 à 20:35
Ton code ou celui ci fonctionne en l'appellant directement dans la Webform (évènement load)
En fait j'ai un stringbuilder dans la classe XHTMLPage que je rempli
donc avec le code ci-dessous et la méthode est appellée directement par
XHTMLPage.
(this.Page as XHTMLPage).TexteHead.Append("teste1");
ou ((XHTMLPage this.Page).TexteHead.Append("teste1");
Bon, maintenant si je copie ma classe XHTLMPage dans le projet de mon
controle serveur et que je copie donc la ligne de code précédente (dans
n'importe quel évènement load, init, prerender ou render ) ca marche
plus et j'ai ceci à l'exécution :
le référence d'objet n'est pas définie à une instance d'un objet
j'ai éventuellement essayé ceci sans succés (j'ai une StackOverflowException) :
public override Page Page
{
get
{
(this.Page as XHTMLPage).TexteHead.Append("teste1");
return base.Page;
}
set
{
base.Page = value;
}
}
Il y a un truc que je dois pas faire... Déjà je trouve bizarre de
devoir copier XHTMLPage dans le répertoire du projet du controle
serveur...
jesusonline
Messages postés6814Date d'inscriptiondimanche 15 décembre 2002StatutMembreDernière intervention13 octobre 201029 21 mars 2005 à 10:12
Tu peux recapituler ce que tu veux faire ? car la je suis un peu perdus :)
Je ne comprend pas non plus pourquoi tu fais ca : (this.Page as
XHTMLPage).TexteHead.Append("teste1"); c'est équivalent a ca
((XHTMLPage)this.Page).Texte.Append("text1");
Et puis d'abord c'est quoi ce Texte.Append ? car ca vient peut etre de la.
Sinon normalement en VB pour moi ca donnerait ca.
public class XHTMLPage inherits system.web.ui.page
public function test as string
return "test"
end function
end class
ensuite dans la page
public class tapage inherits XHTMLPage
end class
dans le code aspx tu mettras ton UC
dans l'uc
public class TonUC inherits system.web.userControl
public sub page_load(sender as object, e as eventargs) handles me.load
label1.text = ctype(me.page, xhtmlpage).test()
end sub
end class
Si j'ai pas fait de connerie ca devrait marcher :)
cs_stailer
Messages postés507Date d'inscriptionjeudi 28 mars 2002StatutMembreDernière intervention13 mai 20091 21 mars 2005 à 12:22
Ooook... Donc en fait je crois qu'on s'est pas compris. Car oui dans le
cas d'un UserControl on peut utiliser une classe du projet et référence
le "load" facilement.
Tandis que moi j'utilise un WebControlLibrary et donc je suis obligé de
copier le fichier XHTMLPage.cs dans ce nouveau projet car je ne peux
pas utiliser celui de mon application (logique puisque le
WebControlLibrary est fait pour être "générique").
Et ensuite le load je suis obligé de le faire comme ca (par surcharge) :
protected override void OnLoad(EventArgs e)
{
base.OnLoad (e);
string a = ((XHTMLPage)this.Page).EcrireHead();
}
Donc c'est la que ca déconne. Sinon j'ai tout fait comme tu as dit et
j'ai une erreur à l'exécution : la cast spécifiée n'est pas valide.
Alors j'ai trouvé la solution et je t'expliquerai le seul petit souci juste après :
1 - dans la page aspx : <head id="head" runat=server>
2 - Déclarer dans le Controle Serveur : protected HtmlGenericControl head;
3 - Surcharge dans le controle serveur :
protected override void OnLoad(EventArgs e)
{
base.OnLoad (e);
head = (HtmlGenericControl)this.Page.FindControl("head");
head.InnerHtml+="Ecrire dans le head";
}
Et ca, c'est impec... mis à part que Visual Studio comporte un bug : à
chaque modification ed la page, il m'efface la partie runat=server dans
le head...
jesusonline
Messages postés6814Date d'inscriptiondimanche 15 décembre 2002StatutMembreDernière intervention13 octobre 201029 21 mars 2005 à 12:46
Ok, en effet, on etait pas sur la meme longueur d'onde ;)
Pour la deuxieme solution, j'ai souvent été confronté à ce bug, la
seule solution que j'ai trouvé c'est de bosser avec Visual Studio 2005
(Whidbey)
VS 2003 modifie sans arret le code HTML, et c'est une erreur pour rester standard
Le problème avec cette solution c'est d'une part le problème si dessus,
et d'autre part il faut rajouter toi meme le runat="server" etc... sous
risque de bug.
Ce que je te proposais c'est que dans XHTMLPage
/// <summary>
/// Summary description for XHTMLPage.
/// </summary>
public class XHTMLPage : System.Web.UI.Page {
private void ConvertToXHTMLStrict() {
ConvertToLowerCase();
AddSelfClose("meta");
AddSelfClose("link");
AddSelfClose("img");
AddSelfClose("hr");
AddTitle();
FixScript();
RemoveAttribute("form", "name");
FixInput();
FixBr();
FixStyle();
FixHtml();
maskScript();
FixAspDotNetJs();
}
private string title = "";
public void setTitle(string LeTitre)
{
title = LeTitre;
}
private void AddTitle()
{
//Ce code n'est pas testé
// delete the current DOCTYPE
int nStart = m_sXHTML.ToLower.IndexOf("<title", 0);
if ( nStart > 0 )
{
int nEnd =
m_sXHTML.ToLower.IndexOf("</title>", 0);
int nHTMLStart = m_sXHTML.ToLower.IndexOf("<html", 0);
int nHTMLEnd = m_sXHTML.IndexOf(">", nHTMLStart + 1);
m_sXHTML.Insert(nHTMLEnd +1, title);
}
}
Ensuite dans toutes tes pages ou tu hérites de XHTMLPage tu auras accés au title
me.setTitle("Le titre")
Ensuite dans ton code de ton control, tu peux faire un truc du genre :
protected override void OnLoad(EventArgs e)
{
base.OnLoad (e);
try
{
( (XHTMLPage)this.Page).SetTitle("Le titre");
}
catch
{
trace.Warn("Attention le controle n'est pas placé dans une page
dérivant de XHTMLPage")
}
}
Et la normalement ca devrait marcher !!!
j'ai malheureusement pas le temps de tester, donc il se peut qu'il faut
encore modifier le code que je t'ai donné ci dessus (par exemple
recuperer ce qu'il y avait d'ecrit dans le title avant de supprimer le
contenu etc...
cs_stailer
Messages postés507Date d'inscriptionjeudi 28 mars 2002StatutMembreDernière intervention13 mai 20091 21 mars 2005 à 14:39
Oui tout à fait, ton code fonctionne... Mais toujours en l'appellant à
partir de la page asp.net et non à partir du contrôle serveur.
Mais c'est pas bien grave, apparemment la disparition du runat=server
sera résolue dans visual studio 2005... en attendant je ferais
attention lors de la modification de mes pages en mode design.