【问题标题】:Rendering C# Objects to Html将 C# 对象渲染为 Html
【发布时间】:2010-10-28 20:02:11
【问题描述】:

我们有一堆域实体,应该呈现为 html 格式,在弹出窗口中显示它们的详细信息。

我很乐意做这样的事情:

Product product = new Product(...);
product.ToHtml();  // or: HtmlRenderer.Render(Product);

但我的主要问题是如何从后面做这些事情。 我有 3 个不同的答案:

1.按代码呈现:

我可以简单地编写用于在 ToHtml 方法 (C#) 中呈现 Html 的代码 - 问题在于它是静态的。如果您想将标题移动一点到中间,您应该更改代码。 此外,C#中的Html缩进很难阅读。

2。使用 XSL:

XSL Files 可以轻松管理 Html 模板,并且使用 XSLT 我可以将 XML 文件转换到文档的正确位置。 已经由其他人编写的解析器(只需要学习语法) ** 为此,我们需要每个对象都可以序列化为 Xml。如果对象更改-> Xml 将更改-> xslt 也需要更改 ** 这也让我可以选择轻松缩进 html,例如:添加 css 功能和\或更改 html 设计

3.使用其他模板引擎:

编写我自己的 C# -> Html 模板引擎,这样它将从文件 (*.template) 中读取模板,并使用反射在模板的正确位置插入正确的属性。 ** 在这个解决方案中,我们有很多可以想到的问题,例如:语法应该是怎样的? 这东西好吗? %名称% %描述% 以及我们如何处理数组? ** 也许我们可以使用现有的引擎(Brail 或 T4-Templating)?

你喜欢什么? 你知道一个好的引擎吗? 现在我更喜欢第二种解决方案,但它会很慢。

谢谢

【问题讨论】:

    标签: c# html rendering template-engine


    【解决方案1】:

    我曾经需要将任何类型的集合呈现到 Html 表中。我在 IEnumerable 上创建了一个扩展方法,该方法具有 css 等的重载。您可以在此处查看我的博客文章:

    http://crazorsharp.blogspot.com/2009/03/cool-ienumberable-extension-method_25.html

    它使用反射来获取对象的所有属性,并渲染一个漂亮的小表格。看看这是否适合你。

    [System.Runtime.CompilerServices.Extension()]
    public string ToHtmlTable<T>(IEnumerable<T> list, string propertiesToIncludeAsColumns = "")
    {
        return ToHtmlTable(list, string.Empty, string.Empty, string.Empty, string.Empty, propertiesToIncludeAsColumns);
    }
    
    [System.Runtime.CompilerServices.Extension()]
    public string ToHtmlTable<T>(IEnumerable<T> list, string tableSyle, string headerStyle, string rowStyle, string alternateRowStyle, string propertiesToIncludeAsColumns = "")
    {
        dynamic result = new StringBuilder();
        if (String.IsNullOrEmpty(tableSyle)) {
            result.Append("<table id=\"" + typeof(T).Name + "Table\">");
        } else {
            result.Append((Convert.ToString("<table id=\"" + typeof(T).Name + "Table\" class=\"") + tableSyle) + "\">");
        }
    
        dynamic propertyArray = typeof(T).GetProperties();
    
        foreach (object prop in propertyArray) {
           if (string.IsNullOrEmpty(propertiesToIncludeAsColumns) || propertiesToIncludeAsColumns.Contains(prop.Name + ",")) {
            if (String.IsNullOrEmpty(headerStyle)) {
                result.AppendFormat("<th>{0}</th>", prop.Name);
            } else {
                result.AppendFormat("<th class=\"{0}\">{1}</th>", headerStyle, prop.Name);
            }
          }
        }
    
        for (int i = 0; i <= list.Count() - 1; i++) {
            if (!String.IsNullOrEmpty(rowStyle) && !String.IsNullOrEmpty(alternateRowStyle)) {
                result.AppendFormat("<tr class=\"{0}\">", i % 2 == 0 ? rowStyle : alternateRowStyle);
    
            } else {
                result.AppendFormat("<tr>");
            }
            foreach (object prop in propertyArray) {
                if (string.IsNullOrEmpty(propertiesToIncludeAsColumns) || propertiesToIncludeAsColumns.Contains(prop.Name + ",")) {
                    object value = prop.GetValue(list.ElementAt(i), null);
                    result.AppendFormat("<td>{0}</td>", value ?? String.Empty);
                }
            }
            result.AppendLine("</tr>");
        }
    
        result.Append("</table>");
    
        return result.ToString();
    }
    

    【讨论】:

      【解决方案2】:

      经过一番研究,我制作了自己的函数来将任何对象转换为 HtmlString。

      VB .Net 代码:

       Public Function ToHtmlString(ByVal fObj As Object) As String
          Dim pType = fObj.GetType()
          Dim props As IList(Of PropertyInfo) = pType.GetProperties()
          Dim value As Object = Nothing
          Dim htmlString As String = "<html><body><form>"
      
          For Each p In props
              value = p.GetValue(fObj, Nothing)
              If value <> Nothing Then
                  htmlString += String.Format("<input type=""hidden"" name=""{0}"" id=""{0}"" value=""{1}""/>", p.Name, value)
              End If
          Next
      
          htmlString += "</form></body></html>"
          Return htmlString.ToString()
      

      它将从特定对象中获取属性名称和值。您可以根据您的

      【讨论】:

        【解决方案3】:

        我非常同意 John Feminella。将 Html 渲染直接集成到您的域实体中是对您的域的可怕污染,具有完全任意和外部的关注。正如 John 所说,这样做会使您的实体变得非常脆弱,并打破这两个关键规则:关注点分离和单一职责。

        根据您给出的选择,#3 是最接近合适的方法。您无需编写自己的模板引擎。网上有很多免费和现成的模板引擎可以很好地完成这项工作(NVelocity、StringTemplate、Brail 等)

        在您的演示文稿/视图中继续呈现它所属的位置...,并且不要用更高级别的问题污染您的域。

        【讨论】:

          【解决方案4】:

          您是否有理由不想创建将域实体对象作为参数的自定义控件 .ascx 文件,然后您可以以任何您想要的方式制作 gui。通过这种方式,您可以动态地将控件添加到页面中,并且只需设置一个属性来填充它们。

          编辑 1: 只需将控件呈现给 HTMLTextWriter,而不是将其放在页面上。

                  StringBuilder outString = new StringBuilder();
                  StringWriter outWriter = new StringWriter(outString);
                  HtmlTextWriter htmlText = new HtmlTextWriter(outWriter);
                  System.Web.UI.WebControls.Label lbl1 = new System.Web.UI.WebControls.Label();
                  lbl1.Text = "This is just a test!";
                  lbl1.ToolTip = "Really";
                  lbl1.RenderControl(htmlText);
                  ViewData["Output"] = outString.ToString();
          

          输出

          <span title="Really">This is just a test!</span>
          

          当然使用您的自定义控件而不是内置控件,但这是一个快速简单的演示。

          【讨论】:

          • 我不在网络团队中工作,我将对象呈现为 html 并将它们发送给其他任何人 - 谁可以在 wpf\palm\web-site 或其他技术中使用它,所以我猜 ascx 对我不好
          • 但是您仍然可以将控件呈现给 html 文本编写器并传递该值。这样,您仍然可以设计和维护 ascx,以方便和简单地编写自己的 xsl 或模板引擎。
          • 在我的答案中添加了代码,以显示 ascx 如何正常工作。
          【解决方案5】:

          就我个人而言,我会结合方法二和三:只需使用反射创建一个通用 XML 文档,比如:

          <object type="xxxx">
              <property name="ttt" value="vvv"/>
              ...
          </object>
          

          并使用 XSTL 样式表从中创建实际的 HTML。

          【讨论】:

            【解决方案6】:

            我真诚地喜欢方法 A。HTML 已经是一个标准,所以您不应该用 XML(通过 XSL - 方法 2)或自定义格式(方法 3)等中间格式来打败自己。

            如果写入/用于 ASP.NET MVC,您可以构建一个 .ASCX(用户控件)来接受您的类型的对象并呈现适当的 HTML。而且你不会得到讨厌的 C# 缩进,也不会突出显示或自动完成。

            您还可以编写多个用户视图来适应一种对象类型的不同场景。

            【讨论】:

            • 我不在网络团队中工作,我将对象呈现为 html 并将它们发送给其他任何人 - 谁可以在 wpf\palm\web-site 或其他技术中使用它,所以我猜想 ascx 对我不好。
            • 在这种情况下,您可以将其序列化为 JSON 格式并发送给其他用户使用。
            • 仍然不够好,我希望它们都获得相同的 UI。不自己处理渲染逻辑。
            • 然后使用方法 2 - 一个 XML 将被翻译成你需要的正确格式。
            • 我喜欢 ASP.Net,我仍然认为您可以将它用于您的目的。您可以在任何页面生命周期之外手动将控件呈现为 html(请参阅blogs.x2line.com/al/articles/859.aspx)。
            【解决方案7】:

            这是您的视图的工作,而不是您的控制器或模型。正如您所怀疑的,使用方法 (1) 会使您的更改非常脆弱。相反,为您希望呈现特定域实体的每种方式编写一个视图片段。然后只需拉入适当的视图即可构建您的最终页面。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-06-12
              • 2017-01-29
              • 2011-06-01
              • 2011-07-12
              • 1970-01-01
              • 2017-05-29
              • 2017-09-20
              相关资源
              最近更新 更多