Каков наилучший способ создания HTML в коде C #? [закрыто]

15

У меня есть убеждение, что разметка должна оставаться в разметке, а не в коде позади.

Я попал в ситуацию, когда считаю приемлемым встроить HTML в код позади. Я хотел бы иметь некоторое согласие относительно того, каковы лучшие практики или должны быть.

Когда допустимо встраивать html в код? Каков наилучший метод для создания этого HTML? (пример: Strings, StringBuilder, HTMLWriter и т. д.)

Родни
источник
попробуйте использовать шаблоны и заполнители, где вы будете плюнуть в эту HTML-разметку.
Юсубов
5
Другой вариант: создать XML на основе вашей модели данных, а затем использовать XSLT для преобразования XML в HTML.
FrustratedWithFormsDesigner
Только что пришел к моему сведению сегодня C # / XAML для HTML5, выглядит многообещающе и может соответствовать вашему сценарию. cshtml5.com
софтведа
проблема с маршрутом XSLT заключается в локализации. Если вам нужны два языка, вам нужны две таблицы стилей XSLT и держите их параллельно. Это ад Лучше просто написать HTML в текстовый файл из C #. использовать String.Format и $ ".. {variable} ..." вместе с WPFLocalization?
Эрик

Ответы:

12

Использование чего-то вроде Razor здесь не применимо? Потому что, если вы делаете много html-генерации с использованием механизма представления, это может сделать это намного проще. Он также был создан для использования вне ASP.NET.

Однако иногда это не то, что вам нужно. Рассматривали ли вы использование класса TagBuilder, который является частью .net (mvc)? В System.Web.UI также есть HtmlWriter (для веб-форм). Я бы порекомендовал один из них, если вы делаете Controlsили Html Helpers.

Даниэль Литтл
источник
3
+1, если вам нужно использовать шаблоны в приложении, бритва - это то, что нужно. Проверьте razorengine @ nuget.org/packages/RazorEngine, если вам нужен отличный вариант для монтирования бритвы в приложении non-asp.net.
Уайетт Барнетт
1
У меня есть аналогичное требование, где мне нужно создать HTML (загружает его) в библиотеке классов. Я хочу использовать бритву для этого, но изо всех сил пытаюсь понять, как поддерживать файлы cshtml в DLL. Как это может объединяться?
Яшвит
Вы можете просто передать любую строку stackoverflow.com/questions/3628895/…
Даниэль Литтл
14

Я бы использовал Html Agility Pack, чтобы собрать HTML, а затем записать его в текстовый файл.

Много человеко-часов ушло на то, чтобы сделать Html Agility Pack надежным и совместимым с HTML.

Я думаю, что это даже включает пример приложения, которое генерирует HTML.

С домашней страницы:

Примеры приложений:

Исправление страницы или генерация. Вы можете исправить страницу так, как вы хотите, изменить DOM, добавить узлы, скопировать узлы, ну ... вы называете это.

Джим Г.
источник
5

Я бы использовал htmltags для создания HTML.

Пример:

var tag = new HtmlTag("span")
    .Text("Hello & Goodbye")
    .AddClass("important")
    .Attr("title", "Greetings")

А потом CSQuery, если я захочу разобрать HTML

Пример:

dom.Select("div > span")
    .Eq(1)
    .Text("Change the text content of the 2nd span child of each div");
jgauffin
источник
2

Конечно, есть библиотеки, такие как HTML Agility Pack, которые могут помочь вам в этих начинаниях.

Если вы действительно не хотите использовать существующую библиотеку и хотите простой, неуклюжий код, мне нравится идея абстрагировать некоторые варианты поведения, как указано в предыдущем ответе. Мне также нравится идея использования базового StringBuilder, а не строки по нескольким причинам:

  1. Строки менее эффективны, чем строитель строк
  2. StringBuilder - это индексируемая структура данных,

Если мне не нужен массивно сконструированный HTML-движок, я бы создал простой, интуитивно понятный интерфейс

AddLineBreak();
AddSimpleTag(string tagName);
AddSimpleTagAt(string tagName, string content, int index);
Output();
Тим С
источник
1
Структура индексируемых данных убедительна, но я не слишком беспокоюсь об эффективности: codinghorror.com/blog/2009/01/…
Джим Г.
1
Я получил несколько раз о тяжести струн, особенно действительно больших струн. StringBuilders более эффективны в использовании памяти и процессора, когда они становятся большими. Итак, в такой реализации, где HTML может стать действительно большим, я бы начал с StringBuilder. Если бы была гарантия, что HTML не станет очень большим, строка, безусловно, будет адекватной.
Тим C
1
Хорошо, если HTML может стать действительно большим, тогда я, конечно, рекомендовал бы пакет Agility HTML. [Я на самом деле рекомендовал HTML Agility Pack за две минуты до этого. :)]
Джим Г.
1

Если вы в конечном итоге используете только строки, не забудьте экранировать все зарезервированные символы HTML в ваших выходных данных.

&    &
>    >
<    &lt;
"    &quot;
'    &apos;

Однако я рекомендую использовать HTML-класс или библиотеку вместо прямой работы со строками. HTMLWriter выглядит довольно хорошим началом.

Майк Кларк
источник
Спасибо за это понимание. Для тех, кто это читает, это то, что я использую для передачи значений данных в шаблоне элемента. Ключ (как рекомендует Майк Кларк) должен знать HTML: <asp: Button ID = "btnEdit" CssClass = "btnmaatwerksmall" runat = "server" Text = "Wijzig" OnClientClick = '<% # String.Format ("OpenChildInEnterprise) ("{0}", "{1}", "{2}"); ", Eval (" Cursus "), Eval (" Omschrijving "), Eval (" Opmerking "))% > '/>
real_yggdrasil
-1

Спустя почти два года после первоначального поста - вот решение, которое хорошо сработало для меня. В целевой документ я помещаю следующее:

<table>    
    <%:theHtmlTableMomToldYouAbout() %>    //# Where I want my rows of table data to go
</table>

вызываемая функция выглядит так:

    public HtmlString theHtmlTableMomToldYouAbout()
    {
        string content = "";
        HtmlString theEnvelopePlease = null;

        for (int i = 0; i < 5; i++)
        {
            content = content + "<tr><td>The Number Is: " + i + "</td></tr>";
        }
        theEnvelopePlease = new HtmlString(content);
        return theEnvelopePlease;      
    }

И результат в браузере будет таким, как и ожидалось:
Число: 0
Число: 1
Число: 2
Число: 3
Число: 4

Когда я иду к источнику, я нахожу следующее:

<table>
    <tr><td>The Number Is: 0</td></tr>
    <tr><td>The Number Is: 1</td></tr>
    <tr><td>The Number Is: 2</td></tr>
    <tr><td>The Number Is: 3</td></tr>
    <tr><td>The Number Is: 4</td></tr>
</table>
WebFixItMan
источник
1
Я укажу, что у вашего решения есть много тех же проблем с тем, что «контент» является неизменной строкой, как описано в постах с низким баллом по этому вопросу.
-1

ПЫЛАТЬ!

var html = "";
html += "<table class='colorful'>";
foreach(var item in collection) {
     html += "<tr>";
     html += "<td class='boldCell'>" + item.PropWhatever + "</td>";
     // more cells here as needed
     html += "</tr>";
}
html += "</table>";
placeholder1.InnerHtml = html;

Я, вероятно, буду за это опускаться, но как бывший дизайнер, который должен был настроить HTML в коде, прежде чем я действительно много знал о .NET, приведенный выше код был намного проще для понимания, чем методы, которые абстрагируют создание HTML. Если вы думаете, что дизайнеру может понадобиться настроить ваш HTML, используйте простые строки, подобные этой.

Я вижу, что многие разработчики упускают при написании HTML в коде то, что в HTML допускаются одинарные или двойные кавычки для атрибутов. Таким образом, вместо экранирования всех кавычек в коде (который выглядит неуклюже как бродяга для не инициированного), просто используйте одинарные кавычки для кавычек html внутри ваших строк.


FINE. Все, что вы связываете ненавистников, связывают мою репутацию. Вот «правильный» способ сделать это без конкатенации строк, но я придерживаюсь своего мнения, что любая обычная страница с обычными таблицами не будет представлять проблем с производительностью за пределами какой-то нелепой Google-подобной шкалы:

var sb = new System.Text.StringBuilder();
sb.Append("<table class='colorful'>");
foreach (var item in collection)
{
     sb.Append("<tr>");
     sb.Append("<td class='boldCell'>" + item.PropWhatever + "</td>");
     // more cells here as needed
     sb.Append("</tr>");
}
sb.Append("</table>");
placeholder1.InnerHtml = sb.ToString();
Грэхем
источник
3
-1 использование + для объединения строк в циклы - худшее, что вы можете сделать.
Даниэль Литтл
продолжение: см. stackoverflow.com/questions/3102806/…
Даниэль Литтл
Ну, для начала, использование +=внутри цикла таким образом не масштабируется вообще; Поскольку строки неизменяемы, вы создаете новую строку каждый раз, когда делаете это. Используйте StringBuilderвместо.
Роберт Харви
3
Почему люди, которые пишут ужасный код, должны делиться своим ужасным кодом с другими людьми.
Ramhound
3
@Ramhound Как насчет If you think a designer might ever have to tweak your HTML, use simple strings like this.трудно понять? У некоторых людей определение ужасного кода - это то, которое покупает миллисекунды производительности, затрачивая много секунд на полное понимание. Ясно, что когда вы ожидаете, что ваш код будет просматриваться или поддерживаться наименьшим общим знаменателем отдельных лиц, можно с уверенностью сказать, что написание кода, который легче понять или настроить, всегда лучше, чем самый чистый или наиболее эффективный код.
maple_shaft