【问题标题】:Convert a single file aspx to code behind将单个文件 aspx 转换为后面的代码
【发布时间】:2010-10-25 16:03:07
【问题描述】:

我正在 VS 2008 .Net 3.5 中开发一个网站(不是 Web 应用程序),它使用单文件 .aspx 模型,其中服务器代码包含在 html 的头部而不是使用 .页面后面的 aspx.cs 代码。

我想快速转换文件以使用代码隐藏模型,但到目前为止,我能做到这一点的唯一方法是删除文件,创建一个新的同名代码隐藏 aspx 页面,然后手动将aspx相关代码复制到.aspx页面,将服务器代码复制到.aspx.cs页面。

有更快的方法吗?

我看过两篇文章,似乎可以回答这个问题,但遗憾的是没有: Working with Single-File Web Forms Pages in Visual Studio .NETHow do you convert an aspx or master page file to page and code behind?

两者都提供了一个简单的解决方案,让 VS 完成腿部工作,您只需将其指向一个文件并射击。无论出于何种原因,它们都不起作用。第一篇文章似乎是指 VS 2002,第二篇文章似乎是指 Web 应用程序。

网站有希望吗?

另外,也许我看错了,单页模型有优势吗?我确实计划很快将整个网站转换为 Web 应用程序,单页模型在 Web 应用程序中是否适用?

【问题讨论】:

    标签: asp.net visual-studio-2008 code-behind


    【解决方案1】:

    非常感谢!如果您的代码是用 VB.Net 编写的,这里是一个稍微修改过的版本。只需在包含 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();
                        }
                    }
                }
            }
    
        }
    }
    

    【讨论】:

    • 如果页面中还没有脚本标签怎么办?那么你的转换器就会坏掉。
    【解决方案2】:

    如果手动转换太费时间,并且自动转换不起作用,我认为您唯一的其他选择就是构建自己的转换器。您可以编写一个简单的控制台应用程序,它在命令行上采用目录路径并处理该目录中的每个文件。这并不难 - 在这里,我会带你开始:

    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 分钟编码,30 分钟调试。有一些明显的错误 - 例如,如果您的代码在 inside 的任何位置包含一个结束脚本标记,那么它将无法正确导出。结果不会很漂亮,但这应该可以处理 90% 的代码,并且您应该能够手动清理任何问题结果。那里,有帮助吗?

    【讨论】:

    • 感谢您抽出宝贵时间提供如此出色的代码示例!
    • 非常好!但是控制声明呢?它们通常在设计器生成的文件中全局声明。就我而言,我有大约 1000 个 aspx 文件需要转换为后面的代码,所以我真的不想做任何手动编辑。
    • 如果页面中还没有脚本标签,转换器将会中断。
    【解决方案3】:

    如果您的 aspx 文件有 2 个部分并且您能够以机械方式将其拆分,为什么您不只编写一个小型解析器来自动化工作?应该不难,它只是纯文本操作和递归文件查找。

    【讨论】:

      【解决方案4】:

      基本上你需要创建一个类文件。从 System.Web.UI.Page 继承类,然后将页面的 page 指令更改为指向后面的代码。

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

      其中 Inherits 是您的类文件的名称,CodeBehind 是您刚刚创建的代码文件。您可能需要重新加载项目以使解决方案资源管理器显示嵌套的文件,但即使您不这样做,它也应该可以工作。

      您还可以查看接受的答案以寻找替代方案。 How does IIS know if it's serving a Web Site or a Web Application project?

      【讨论】:

      • 感谢您的想法。我仍在寻找一种更简单的方法,因为该网站有几十个页面。我的方法,实际上更类似于 Serapth 建议的方法,但我可以看到你的方法也有效。这些可能是唯一的选择,但是如果您按照我提供的两个链接进行操作,您会发现曾经有一种自动化方式...
      • 如果有“数十”页,我认为这可以在几个小时内完成(虽然很烦人的小时),或者如果有“数百页” ,也许编写一个简单的控制台应用程序来使用正则表达式为您解析页面并写入文件系统。
      【解决方案5】:

      说实话,我不知道有什么捷径。

      您最好的选择可能是创建一个新页面并复制粘贴,直到一切正常,然后删除您的源,将您的新文件重命名为旧名称并重建。

      不理想,但可能是最快/最干净/最安全的移植方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-16
        • 2016-02-20
        • 2012-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多