Convert a single file aspx to code behind

asp.netcode-behindvisual-studio-2008

I'm working on a web site (not a web application) in VS 2008 .Net 3.5 and it uses the single file .aspx model where the server code is included in the head portion of the html instead of using a .aspx.cs code behind page.

I'd like to quickly convert the files to use the code-behind model, but so far the only way I can do this is by removing the file, creating a new, code-behind aspx page of the same name, then manually copying in the aspx related code to the .aspx page and the server code to the .aspx.cs page.

Is there a faster way to do this?

I have seen two article that seem to answer this question, but unfortunately don't:
Working with Single-File Web Forms Pages in Visual Studio .NET and
How do you convert an aspx or master page file to page and code behind?

Both offer a simple solution whereby VS does the leg work, you just point it to a file and shoot. For whatever reason, they aren't working. The first article seems to refer to VS 2002 and the second seems to refer to a web application.

Is there any hope for a web site?

Also, maybe I'm seeing this the wrong way, is there an advantage to the single page model? I do plan on converting the whole web site to a web application soon, does the single page model work well in web applications?

Best Answer

If manual conversion is too time-intensive, and the automatic conversion isn't working, I think your only other option would be to build your own converter. You could write a simple console app which takes a directory path on the command line and processes every file in that directory. This isn't too hard - here, I'll get you started:

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 minutes coding, 30 minutes debugging. There are some obvious bugs - like, if your code contains a closing script tag anywhere inside, then it won't get exported correctly. The results won't be pretty, but this should take care of 90% of your code, and you should be able to clean up any problem results manually. There, does that help?