2012-07-10 8 views
7

Sto provando ancora una volta per contattare esperti di asp.net e sperare di ottenere una risposta. Sono davvero bloccato qui e chiedo aiuto. Spero che la mia domanda non vada giù votata, e che potrei ottenere una risposta puramente dal punto di vista tecnico, invece che la gente semplicemente giudica il mio approccio.Identifica etichetta e pulsante di controllo in ogni pagina del progetto web

All'inizio ho postato domanda come segue: asp.net convert asp.net page into Page variable

Poi ho guardato seguente pagina, ma ancora la sua non funziona per me.

Load an ASP.NET 2.0 aspx page using System.Reflection?

Dentro la mia applicazione web, vorrei essere in grado di fare riferimento a pagine web in qualsiasi luogo nel mio codice come "WebForm1.aspx" e ottenere un elenco dei controlli in quella pagina. Per favore basta guardarlo da questo punto di vista e non analizzarlo più. È possibile?

nella mia pagina variabile p, non sembrano avere alcun controllo per WebForm1.aspx

Ecco il mio codice.

Per favore aiuto.

protected void Page_Load(object sender, EventArgs e) 
    { 
     string[] filePaths = Directory.GetFiles(Server.MapPath("~/"), "*.*", SearchOption.AllDirectories); 

     foreach (string filepath in filePaths) 
     { 
      if (filepath.EndsWith(".aspx")) 
      { 
       Response.Write(filepath + "<br/>"); 

       string[] folders = filepath.Split('\\'); 
       string filename = folders[folders.Count() - 1]; 
       string fullpath = "~/" + filename; 

       Page p = BuildManager.CreateInstanceFromVirtualPath("~/"+fullpath, typeof(Page)) as Page; 

       List<String> controlList = new List<String>(); 
       ResourceManager.AddControls(p.Controls, controlList); 

       foreach (string str in controlList) 
       { 
        Response.Write(str + "<br/>"); 
       } 


      } 
     } 
+0

È il applicazione asp.net sito Web o applicazione web? – Candide

+0

web application .. grazie –

+0

penso sia una buona domanda –

risposta

4

A causa della ASP.NET Page Life Cycle, i controlli vengono creati solo per l'elaborazione della richiesta (IHttpHandler.ProcessRequest(HttpContext)).

Prima di iterare oltre i controlli necessari per eseguire il codice qui sotto:

//this is necessary, Otherwise "Default.aspx" will show the contents of "WebForm1.aspx". 
HttpWorkerRequest hwr = new SimpleWorkerRequest(this.TxtPageVirtualPath.Text, "", tw); 
HttpContext fakeContext = new HttpContext(hwr); 
((IHttpHandler)p).ProcessRequest(fakeContext); 

Di seguito si riporta il codice completo per Default.aspx:

using System; 
using System.Data; 
using System.Configuration; 
using System.Collections; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using System.Web.Compilation; 
using System.Collections.Generic; 
using System.Resources; 
using System.IO; 
using System.Web.Hosting; 

namespace _1423280WebApp 
{ 
    public partial class _Default : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 

     } 

     protected void BtnLoad_Click(object sender, EventArgs e) 
     { 
      Page p = BuildManager.CreateInstanceFromVirtualPath(this.TxtPageVirtualPath.Text, typeof(Page)) as Page; 

      List<String> controlList = new List<String>(); 

      MemoryStream ms = new MemoryStream(); 
      TextWriter tw = new StreamWriter(ms); 
      HtmlTextWriter htw = new HtmlTextWriter(tw); 

      //this is necessary, Otherwise "Default.aspx" will show the contents of "WebForm1.aspx". 
      HttpWorkerRequest hwr = new SimpleWorkerRequest(this.TxtPageVirtualPath.Text, "", tw); 
      HttpContext fakeContext = new HttpContext(hwr); 

      ((IHttpHandler)p).ProcessRequest(fakeContext); 

      //I could not compile this part in VS2005 
      //ResourceManager.AddControls(p.Controls, controlList); 


      this.TxtListControls.Text = ""; 
      foreach (Control ctr in p.Controls) 
      { 
       this.TxtListControls.Text += this.recursiveControls(p, ""); 
      } 
     } 

     public string recursiveControls(Control control, string ident) 
     { 
      string retStr = 
       String.Format(
        ident + "D='{0}', ClientID='{1}', Type=='{2}' \n", 
        control.ID, 
        control.ClientID, 
        control.GetType().FullName); 
      foreach (Control innerCtr in control.Controls) 
      { 
       retStr += this.recursiveControls(innerCtr, " " + ident); 
      } 

      return retStr; 
     } 
    } 
} 
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="_1423280WebApp._Default" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "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"> 
    <div> 
     Get List of Controls from:<br /> 
     <asp:TextBox ID="TxtPageVirtualPath" runat="server">~/webform1.aspx</asp:TextBox><br /> 
     <asp:Button ID="BtnLoad" runat="server" OnClick="BtnLoad_Click" Text="Load" /><br /> 
     Controls:<br /> 
     <asp:TextBox ID="TxtListControls" runat="server" Height="328px" TextMode="MultiLine" 
      Width="100%"></asp:TextBox></div> 
    </form> 
</body> 
</html> 

Solution con la completa codice di esempio: q_11423280WebApp.7z

+0

+1. Buona soluzione – NotMe

2

Ecco un'alternativa al caricamento dei controlli:

protected void Page_Load(object sender, EventArgs e) 
{ 
    Type type = BuildManager.GetCompiledType("~/Default.aspx"); 
    var page = (Default)Activator.CreateInstance(type); 
    ((IHttpHandler)page).ProcessRequest(HttpContext.Current); 
    var count = page.Controls.Count; 
    Response.Clear(); // Because we use HttpContext.Current the response has a lot of stuff 
} 
+0

Grazie Ingenu !!!! c'è un modo in cui posso scappare non passando a Default sulla terza linea? In questo modo ho potuto passare attraverso diverse pagine automaticamente. Per ora, la seguente riga non funzionerà se voglio scorrere tra le diverse pagine: var page = (Default) Activator.CreateInstance (type); –

+0

Non vedo alcun motivo per cui no: 'var page = (Pagina) Activator.CreateInstance (type);' funziona altrettanto bene perché 'Default' eredita da' Page'. – Candide

Problemi correlati