7

我正在使用 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 应用程序中是否运行良好?

4

5 回答 5

19

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

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

于 2009-05-18T22:35:55.437 回答
3

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

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

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

您还可以查看接受的答案以寻找替代方案。IIS 如何知道它是服务于网站还是 Web 应用程序项目?

于 2009-05-12T20:27:40.540 回答
2

老实说,我不知道捷径。

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

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

于 2009-05-12T19:59:10.493 回答
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();
                    }
                }
            }
        }

    }
}
于 2009-11-20T12:26:50.530 回答
0

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

于 2009-05-15T21:42:10.633 回答