在C#中生成HTML页面-最佳实践

5

我需要在我的C#代码中生成一个大的HTML页面(不是一个网站,只是一个大型单页HTML报告)。

页面包含多个部分,编译在一个页面中。每个部分都包含CSS样式、JavaScript部分和与其相关的正文。CSS样式是静态部分,脚本和正文部分是使用不同的输入数据(CSV文本)生成的。

我第一个简单的解决方案是创建一个构建器函数来简化所有生成操作:

 private static string BuildHtmlPage(string[] cssParts, string[] scriptParts, string[] bodyParts)
    {
        var htmlPage = "";
        htmlPage += @"<!DOCTYPE HTML>
 <html>";

htmlPage += "\n<head>";

        htmlPage += "\n<style>\n";
            foreach (var cssPart in cssParts)
            {
                htmlPage += cssPart +"\n";
            }
        htmlPage += "</style>\n";

        htmlPage += @"<script type=""text/javascript"">";
        htmlPage += "window.onload = function() {";

            foreach (var scriptPart in scriptParts)
            {
                htmlPage += scriptPart + "\n";
            }

        htmlPage += @"}
</script>";

htmlPage += "\n</head>";

        htmlPage += "\n<body>\n";
            foreach (var bodyPart in bodyParts)
            {
                htmlPage += bodyPart + "\n";
            }
        htmlPage += "\n</body>";

htmlPage += "\n</html>";

return htmlPage;

    }

然后生成一个“小型”的HTML部分,并像这样使用它:
var htmlResult = BuildHtmlPage(
            new [] {style1, style2 },
            new [] {script1, script2, script3 },
            new [] {body1, body2, body3 }
        );

这使得我的代码变得更加清晰,但由于许多 HTML 代码混杂在 C# 代码中,它仍然看起来很丑陋且难以维护。

您能提出处理此类任务的想法吗?首先,我的意思是将 HTML 代码与 C# 分离。


2
看看 Razor。它有可嵌入的表单。 - Daniel A. White
你也可以尝试使用固定内容和脚本创建页面,并尝试使用JavaScript格式化数据。 - Caramiriel
1
我同意使用剃刀建议。另一种方法是:虽然并非所有的HTML都是有效的XML,但您可以构建类似于有效XML的HTML,从而利用像LINQ to XML这样的XML库。此外,如果生成的HTML不需要被人阅读,则应删除所有不必要的格式,例如空格或换行符。 - Corak
4
如果你不想使用 Razor,那至少应该使用 StringBuilder 而不是将字符串连接起来。 - Camilo Terevinto
我认为你已经自己回答了你的问题。在我看来,你似乎正在重新发明轮子,而正确的方法应该是“如何在用户界面中呈现大量数据”? - EdSF
2个回答

9
这里有一个非常简洁的方法,可以为您提供所有来自Web应用程序的功能、Visual Studio对HTML的格式化、Razor (基本上是MVC项目中的所有内容):
  1. 创建一个ASP.NET MVC项目。
  2. 创建你的视图,就像你创建一个MVC视图一样。
  3. 当你满意外观和感觉时,创建另一个应用程序(控制台、Windows窗体等),并引用MVC应用程序。
  4. 控制台应用程序可以从MVC应用程序获取视图,而不是使用浏览器。
以下假设我们有一个控制台应用程序将使用MVC应用程序。 配置MVC应用程序的步骤: 这些步骤将预编译您的视图。因此,稍后我们将能够直接从控制台应用程序访问视图。
  1. Right click your MVC project and add these NuGet packages:
    1. RazorGenerator.MsBuild
    2. RazorGenerator.Mvc
  2. Open your MVC project's .csproj file in notepad and add these elements:

    1.In the topmost PropertyGroup element, add <MvcBuildViews>true</MvcBuildViews>

    2.At the very end of the file add:

    <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
        <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
    </Target>
    

    3.Build the project. We need to make sure the views are compiled. To make sure it is actually being compiled, in the .cshtml file write some code that does not compile. When you compile, if everything has been setup properly, the compilation should fail indicating that the compiler is compiling the views also. If it does not fail, then one of the above steps was not done as specified. If it fails, good news. Remove the error and compile again.

配置控制台应用程序的步骤

  1. 右键单击项目并添加RazorGenerator.Testing。虽然我们不是在测试,但是我们将使用此库来生成视图的 HTML。
  2. 像引用 DLL 一样引用 MVC 应用程序。
  3. 右键单击 MVC 项目引用并从上下文菜单中选择View in Object Browser。您的视图将位于 ASP 命名空间中,请注意视图的名称。
  4. 按下面的Usage所示创建一个视图的实例,完成配置过程。例如,我的视图名称为_Views_Test_Index_cshtml

如您所见,以上大部分步骤只是设置。

用法

我做了一个快速测试,以下是我所需的全部代码:

var view = new ASP._Views_Test_Index_cshtml();
view.ViewBag.Model = new List<string>() { "One", "Two", "Three" };
var html = view.RenderAsHtml();

由于View.Model是只读的,我使用了ViewBag.Model来设置视图的模型。以下是视图代码:

@{
    ViewBag.Title = "Index";
    var MyModel = this.ViewBag.Model as List<string>;
}

@for (int i = 0; i < MyModel.Count ; i++)
{
    <label>@MyModel[i]</label>
}

以下是生成的HTML代码:

<label>One</label>
<label>Two</label>
<label>Three</label>

您可以将需要传递到视图中的任何内容放入ViewBag中。您可能会发现这篇文章很有帮助。


1
感谢Yoshi提供详细的答案。看起来你的方法适用于创建Web项目,但我只需要创建几个大型HTML文件。目前对我来说,为此目的添加一个新实体似乎过于冗余和不合理,因此我想找到任何使用纯dotnet的解决方案。 - Vladimir
@vladimir 不,这不是用于创建Web项目的。它使用MVC框架为您生成文件。它也不过度;我只花了5分钟就完成了。怎么会过度呢? - CodingYoshi
好的,谢谢。我会尝试使用它并提供反馈。 - Vladimir
我打算尝试使用.Net Core。 - Renato Sanhueza
@CodingYoshi,感谢您提供的解决方案。view.RenderAsHtml(); 不应用CSS,有没有办法让它工作呢? - NTinkicht
显示剩余2条评论

0

我也曾经搜索过这个问题的答案,但是没有一个解决方案让我满意。因此,我自己编写了一个库,最近我在两家公司工作时使用了一些解决方案。

大多数提出的解决方案要么是自己构建字符串,要么是使用你可能不想依赖的库(例如Razor)。

请允许我自荐我的库:)

  • 开源(MIT许可证)
  • 无依赖(因此可以在任何.Net Core项目、独立库、Web应用程序、控制台应用程序中使用)
  • 具有相当不错的类似DSL的语法,以及常规语法(例如new A(myHref)
  • 创建了一个内存中的HTML对象图,可以像普通的C#对象一样创建和操作,或者转换为字符串(包括编码等)
  • 如果需要,可以序列化为HTML或XML(类似XHTML)

示例:

   var fruits = new[] { "Apple", "Banana", "Cherry" };
   var html =
        _<Html>(
            _<Head>(
                _<Title>("Hello, World!")
            ),
            _<Body>(
                _<H1>("Hello, World!"),
                _<P>(
                    _("This is a paragraph with <>. "), // Becomes plain text, not an element. Text is escaped. 
                    _<Ul>(
                        fruits.Select(_<Li>)
                    )
                ),
                _UNSAFE("This will not be <b>escaped</b>") // Allows any HTML, don't use this with untrusted content. 
            )
        );
   string actualHtmlString = html.ToHtml();

更多的文档、源代码和使用说明,请参见:

https://github.com/narve/DV8.Html or https://www.nuget.org/packages/DV8.Html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接