2009-05-12 28 views
6

Sto lavorando su un sito Web (non un'applicazione Web) in VS 2008 .Net 3.5 e utilizza il modello di file singolo .aspx in cui il codice del server è incluso nella parte principale del codice HTML invece di utilizzare un codice .aspx.cs dietro la pagina.Convertire un singolo file aspx nel codice

Mi piacerebbe convertire rapidamente i file per utilizzare il modello code-behind, ma finora l'unico modo per farlo è rimuovendo il file, creando una nuova pagina di aspx con lo stesso nome e code-behind , quindi copiando manualmente il codice relativo ad aspx nella pagina .aspx e il codice del server nella pagina .aspx.cs.

C'è un modo più veloce per farlo?

ho visto due articolo che sembrano rispondere a questa domanda, ma purtroppo non lo fanno: Working with Single-File Web Forms Pages in Visual Studio .NET e How do you convert an aspx or master page file to page and code behind?

Entrambi offrono una soluzione semplice per cui VS fa il lavoro di gambe, è sufficiente puntarlo un file e spara. Per qualsiasi motivo, non stanno funzionando. Il primo articolo sembra riferirsi a VS 2002 e il secondo sembra riferirsi a un'applicazione web.

C'è qualche speranza per un sito web?

Inoltre, forse sto vedendo questo nel modo sbagliato, c'è un vantaggio per il modello a pagina singola? Pianifico presto la conversione dell'intero sito Web in un'applicazione Web, il modello a pagina singola funziona bene nelle applicazioni Web?

risposta

19

Se la conversione manuale è troppo dispendiosa in termini di tempo e la conversione automatica non funziona, penso che l'unica altra opzione sarebbe creare il proprio convertitore. Potresti scrivere una semplice app per console che prende un percorso di directory sulla riga di comando ed elabora tutti i file in quella directory. Questo non è troppo difficile - qui, ti inizierò:

using System; 
using System.IO; 

class Program 
{ 
    const string ScriptStartTag = "<script language=\"CS\" runat=\"server\">"; 
    const string ScriptEndTag = "</script>"; 

    static void Main(string[] args) 
    { 
     DirectoryInfo inPath = new DirectoryInfo(args[0]); 
     DirectoryInfo outPath = new DirectoryInfo(args[0] + "\\codebehind"); 
     if (!outPath.Exists) inPath.CreateSubdirectory("codebehind"); 
     foreach (FileInfo f in inPath.GetFiles()) 
     { 
      if (f.FullName.EndsWith(".aspx")) 
      { 
       // READ SOURCE FILE 
       string fileContents; 
       using (TextReader tr = new StreamReader(f.FullName)) 
       { 
        fileContents = tr.ReadToEnd(); 
       } 
       int scriptStart = fileContents.IndexOf(ScriptStartTag); 
       int scriptEnd = fileContents.IndexOf(ScriptEndTag, scriptStart); 
       string className = f.FullName.Remove(f.FullName.Length-5).Replace("\\", "_").Replace(":", "_"); 
       // GENERATE NEW SCRIPT FILE 
       string scriptContents = fileContents.Substring(
        scriptStart + ScriptStartTag.Length, 
        scriptEnd-(scriptStart + ScriptStartTag.Length)-1); 
       scriptContents = 
        "using System;\n\n" + 
        "public partial class " + className + " : System.Web.UI.Page\n" + 
        "{\n" + 
        " " + scriptContents.Trim() + 
        "\n}"; 
       using (TextWriter tw = new StreamWriter(outPath.FullName + "\\" + f.Name + ".cs")) 
       { 
        tw.Write(scriptContents); 
        tw.Flush(); 
       } 
       // GENERATE NEW MARKUP FILE 
       fileContents = fileContents.Remove(
        scriptStart, 
        scriptEnd - scriptStart + ScriptEndTag.Length); 
       int pageTagEnd = fileContents.IndexOf("%>"); 
       fileContents = fileContents.Insert(PageTagEnd, 
        "AutoEventWireup=\"true\" CodeBehind=\"" + f.Name + ".cs\" Inherits=\"" + className + "\" "); 
       using (TextWriter tw = new StreamWriter(outPath.FullName + "\\" + f.Name)) 
       { 
        tw.Write(fileContents); 
        tw.Flush(); 
       } 
      } 
     } 
    } 
} 

30 minuti di codifica, 30 minuti di debug.Ci sono alcuni bug ovvi - come, se il tuo codice contiene un tag di script di chiusura ovunque all'interno di, quindi non verrà esportato correttamente. I risultati non saranno belli, ma questo dovrebbe occuparsi del 90% del codice e dovresti essere in grado di pulire manualmente i risultati di eventuali problemi. Lì, ti aiuta?

+0

+1 per fare il miglio supplementare fornendo un esempio di codice. – Armstrongest

+0

Grazie per il tempo dedicato a fornire un esempio di codice così fantastico! –

+0

Molto bello! Ma che dire delle dichiarazioni di controllo? Normalmente vengono dichiarati globalmente nel file generato dal designer. Nel mio caso ho circa 1000 file aspx che devono essere convertiti in code behind, quindi mi piacerebbe davvero non fare alcuna modifica manuale. – Marcus

2

Non conosco un modo di scelta rapida per essere onesti.

Probabilmente la soluzione migliore è creare una nuova pagina e copiare la pasta fino a quando tutto funziona, quindi eliminare la fonte, rinominare il nuovo file con il vecchio nome e ricostruire.

Non ideale, ma probabilmente il modo più veloce/più pulito/più sicuro per eseguire il porting.

3

Fondamentalmente è necessario creare un file di classe. Eredita la classe da System.Web.UI.Page e quindi modifica la direttiva di pagina della pagina in modo che punti al codice sottostante.

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

Dove Inherits è il nome del file di classe, e la CodeBehind è il file di codice che avete appena creato. Potrebbe essere necessario ricaricare il progetto per far sì che explorer della soluzione visualizzi il file annidato, ma anche se non lo si dovrebbe fare dovrebbe funzionare.

È inoltre possibile controllare la risposta accettata per un'alternativa. How does IIS know if it's serving a Web Site or a Web Application project?

+0

Grazie per il pensiero. Sto ancora cercando un modo più semplice, dato che il sito ha dozzine di pagine. Il mio metodo è in realtà più simile a quello suggerito da Serapth, ma posso vedere che anche il tuo funziona. Queste potrebbero essere le uniche scelte, ma se segui i due link che ho incluso, vedrai che a un certo punto c'è stato un modo automatico ... –

+0

Se ci sono "dozzine" di pagine, penserei che questo potrebbe essere fatto nel giro di poche ore (albiet, ore dolorosamente fastidiose), o se ci sono "centinaia di dozzine" di pagine, magari scrivendo una semplice app per console per analizzare le pagine per te usando le espressioni regolari e scrivendo sul file system. –

0

se il file aspx ha 2 sezioni e sei in grado di dividerlo in modo meccanico perché non scrivi solo un parser piccolo per automatizzare il lavoro? Non dovrebbe essere difficile, è solo una semplice manipolazione del testo e una ricerca di file ricorsiva.

1

Grazie mille! Ecco una versione leggermente modificata se il tuo codice è scritto in VB.Net. Basta compilare ed eseguire il convertitore in ogni cartella che contiene siti aspx.

using System.IO; 
namespace Converter 
{ 
    class Program 
    { 
     const string ScriptStartTag = "<script runat=\"server\">"; 
     const string ScriptEndTag = "</script>"; 

     static void Main(string[] args) 
     { 
      string currentDirectory = System.Environment.CurrentDirectory; 

      var inPath = new DirectoryInfo(currentDirectory); 
      var outPath = new DirectoryInfo(currentDirectory); 
      if (!outPath.Exists) inPath.CreateSubdirectory("codebehind"); 
      foreach (FileInfo f in inPath.GetFiles()) 
      { 
       if (f.FullName.EndsWith(".aspx")) 
       { 
        // READ SOURCE FILE 
        string fileContents; 
        using (TextReader tr = new StreamReader(f.FullName)) 
        { 
         fileContents = tr.ReadToEnd(); 
        } 
        int scriptStart = fileContents.IndexOf(ScriptStartTag); 
        int scriptEnd = fileContents.IndexOf(ScriptEndTag, scriptStart); 
        string className = f.FullName.Remove(f.FullName.Length - 5).Replace("\\", "_").Replace(":", "_"); 
        // GENERATE NEW SCRIPT FILE 
        string scriptContents = fileContents.Substring(
         scriptStart + ScriptStartTag.Length, 
         scriptEnd - (scriptStart + ScriptStartTag.Length) - 1); 
        scriptContents = 
         "Imports System\n\n" + 
         "Partial Public Class " + className + " \n Inherits System.Web.UI.Page\n" + 
         "\n" + 
         " " + scriptContents.Trim() + 
         "\nEnd Class\n"; 
        using (TextWriter tw = new StreamWriter(outPath.FullName + "\\" + f.Name + ".vb")) 
        { 
         tw.Write(scriptContents); 
         tw.Flush(); 
        } 
        // GENERATE NEW MARKUP FILE 
        fileContents = fileContents.Remove(
         scriptStart, 
         scriptEnd - scriptStart + ScriptEndTag.Length); 
        int pageTagEnd = fileContents.IndexOf("%>"); 

        fileContents = fileContents.Insert(pageTagEnd, 
         "AutoEventWireup=\"false\" CodeBehind=\"" + f.Name + ".vb\" Inherits=\"" + className + "\" "); 
        using (TextWriter tw = new StreamWriter(outPath.FullName + "\\" + f.Name)) 
        { 
         tw.Write(fileContents); 
         tw.Flush(); 
        } 
       } 
      } 
     } 

    } 
} 
+0

Grazie per il contributo :) –

+0

e se non ci sono ancora tag di script nelle pagine? allora il tuo convertitore si romperebbe. – Smith

Problemi correlati