2009-05-25 53 views
7

我們有許多應該呈現爲html格式的域實體,它們在彈出窗口中顯示它們的細節。將C#對象渲染爲Html

我會很高興做這樣的事情:

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

,但我的主要問題是如何從背後做這個東西。 我有3個不同的答案:

1渲染通過代碼:

我可以簡單地寫我的渲染HTML中的ToHtml方法(C#)代碼 - 問題是,這是靜態。如果您想將標題移動到中間,則應更改代碼。此外,在C#中閱讀Html縮進非常困難。

2.使用XSL:

XSL文件可以輕鬆地管理HTML模板和使用XSLT我可以將XML文件到文件的正確的地方。 解析器已經由其他人編寫(只需要學習語法) **因此,我們需要每個對象都可以序列化爲Xml。如果對象發生了變化 - > Xml將被更改 - > xslt也需要更改 **這也會讓我選擇簡單地縮進html,例如:添加css功能和\或更改html設計使用

3.其他模板引擎:

寫我自己的C# - > HTML模板引擎,它會讀取文件的模板(* .template),並會在正確的地方插入正確的屬性使用反射的模板。 **在這個解決方案中,我們有很多我們可以想到的問題,例如:語法應該如何? 這個東西好嗎? %名稱%%描述% 以及我們如何處理數組? **也許我們可以使用現有的引擎(Brail或T4模板)?

你更喜歡什麼? 你知道一個好的引擎嗎?現在我更喜歡第二種解決方案,但它會很慢。

謝謝

回答

3

我完全同意John Feminella。將Html渲染直接集成到你的域實體中是對你的域名的一種可怕的污染,完全是任意的和外部的關注。就像約翰說的那樣,你會通過這樣做讓你的實體非常脆弱,並且破壞這些關鍵規則:分離關注點和單一責任。

從您給出的選擇中,#3是最接近它的一種適當方式。你不需要編寫你自己的模板引擎。網絡上有很多免費的現成模板引擎,可以完成這項工作(NVelocity,StringTemplate,Brail等等)。

在您的演示文稿/視圖中保持渲染位置,並且不要以更高級別的關注來污染你的域名。

3

這是你的看法的工作,而不是你的控制器或模型。正如您懷疑的那樣,使用方法(1)會使您的更改非常脆弱。相反,爲每個你想呈現特定域實體的方式編寫一個視圖片段。然後簡單地拉入適當的視圖來構建最終頁面。

2

我真誠地喜歡方法A. HTML已經是一個標準,所以你不應該用XML(通過XSL - 方法2)或自定義格式(方法3)等中間格式來打破自己。

如果在ASP.NET MVC中寫入,您可以構建一個.ASCX(用戶控件),它將接受您的類型的對象並呈現合適的HTML。你不會得到令人討厭的C#縮進,沒有突出顯示或自動完成。

您還可以編寫多個用戶視圖以適應一種對象類型的不同方案。

+0

我不是在一個web團隊中工作,我將對象作爲html渲染併發送給其他任何人 - 誰可以在wpf \ palm \ web-site或其他技術中使用它,所以我想ascx對我不好。 – rabashani 2009-05-25 22:07:29

+0

在這種情況下,您可以使用JSON格式將其序列化並將其發送給其他用戶使用。 – shahkalpesh 2009-05-25 22:11:27

0

是不是有一個原因,你不想創建一個自定義控件.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> 

當然可以用,而不是一個內置的控制,但是這是一個快速簡便的演示自定義控件。

5

我曾經需要將任何類型的集合呈現給Html表格。我在IEnumerable <T>上創建了一個擴展方法,該方法對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(); 
} 
0

就個人而言,我會結合方法二和三:只要創建使用反射通用的XML文檔,說:

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

,並使用XSTL樣式表來創建這個實際的HTML。

1

經過一番研究,我做了我自己的函數來轉換任何對象toHtmlString。

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() 

它將從特定對象獲得屬性名稱和值。你可以根據你的需要操作html