Вопрос

У нас есть куча объектов домена, которые должны быть переведены в формат 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-Templating)?

Что вы предпочитаете?знаете ли вы хороший двигатель?на данный момент я предпочитаю второе решение, но оно будет очень медленным.

Спасибо

Это было полезно?

Решение

Я не могу не согласиться с Джоном Феминеллой.Интеграция Html-рендеринга непосредственно в объекты вашего домена - это ужасное загрязнение вашего домена совершенно произвольными и внешними причинами.Как сказал Джон, сделав это, вы сделаете свои сущности очень хрупкими и нарушите оба этих критических правила:Разделение забот и Единая ответственность.

Из приведенных вами вариантов № 3 наиболее близок к подходящему способу сделать это.Вам не нужно писать свой собственный шаблонизатор.В сети есть множество бесплатных и готовых шаблонизаторов, которые справятся с этой задачей более чем адекватно (NVelocity, StringTemplate, Brail и т.д.и т.д.)

Продолжайте визуализировать там, где это необходимо belongs...in ваша презентация / представление и не загрязняйте свой домен проблемами более высокого уровня.

Другие советы

Однажды у меня возникла необходимость отобразить коллекцию любого типа в 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();
}

Это работа вашего представления, а не ваших контроллеров или моделей.Как вы подозреваете, использование метода (1) сделает ваши изменения очень хрупкими.Вместо этого напишите фрагмент представления для каждого способа, которым вы хотели бы отобразить конкретный объект домена.Затем просто выберите соответствующие представления, чтобы создать свою окончательную страницу.

Я искренне предпочитаю метод А.HTML уже является стандартом, поэтому вам не стоит слишком утруждать себя промежуточными форматами, такими как XML (через XSL - метод 2) или пользовательский формат (метод 3).

При записи в / for ASP.NET Однако вы могли бы создать MVC .ASCX (пользовательский элемент управления), который принимал бы объект вашего типа и отображал соответствующий HTML.И вы не получите неприятного отступа C #, ни выделения, ни автозаполнения.

Вы также могли бы написать несколько пользовательских представлений, чтобы приспособить различные сценарии для одного типа объекта.

После небольшого исследования я создал свою собственную функцию для преобразования любого объекта в 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()

он получит имя свойства и значение от конкретного объекта.вы можете манипулировать html на основе вашего

Лично я бы объединил второй и третий методы:Просто создайте общий XML-документ, используя отражение, скажем:

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

и используйте таблицу стилей XSTL, чтобы создать из этого фактический HTML-код.

Есть ли причина, по которой вы не хотите создавать пользовательский файл control .ascx, который принимает объект domain entities в качестве аргумента, а затем вы можете создать графический интерфейс любым удобным для вас способом.Таким образом, вы могли бы динамически добавлять элементы управления на страницу и просто устанавливать свойство для их заполнения.

Правка 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>

Конечно, используйте свой пользовательский элемент управления вместо встроенного, но это была быстрая и простая демонстрация.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top