Как вы обрабатываете разрывы строк в представлении HTML Encoded MVC?

Я не уверен, как лучше всего справиться с этим. В моем индексном представлении я отображаю сообщение, содержащееся в TempData["message"]. Это позволяет мне отображать определенные сообщения об ошибках или информационные сообщения пользователю при переходе из другого действия (например, если пользователь пытается ввести действие «Редактировать», когда у него нет доступа, он отбрасывает его обратно в индекс с сообщением «Вы не авторизованы для редактирования этих данных»).

Перед отображением сообщения я запускаю Html.Encode(TempData["message"]). Однако недавно я столкнулся с проблемой, когда для более длинных сообщений я хочу иметь возможность отделять строки с помощью разрывов строк (<br>). К сожалению (и очевидно), <br> кодируется Html.Encode, так что это не приводит к фактическому разрыву строки.

Как правильно обрабатывать разрывы строк в строках с кодировкой Html?


person KallDrexx    schedule 04.10.2010    source источник
comment
почему вы кодируете HTML? (Это полезно для ввода, возвращаемого из текстовых полей формы от клиента. Если вы создаете свои собственные строки ошибок/сообщений, вам не нужно кодировать.)   -  person Roger    schedule 05.10.2010
comment
Потому что сообщение может содержать что-то из базы данных. Что делать, если я хочу сообщить пользователю, что вы успешно сохранили запись ‹название›   -  person KallDrexx    schedule 05.10.2010
comment
@ KallDrexx, да, это имеет смысл. Спасибо за разъяснения!   -  person Roger    schedule 05.10.2010


Ответы (5)


Я согласен с комментарием @Roger - на самом деле нет необходимости кодировать что-либо, над чем у вас есть полный контроль.

Если вы все же хотите перестраховаться (что неплохо), вы можете использовать библиотеку Microsoft AntiXss и используйте метод .GetSafeHtmlFragment(input) — см. Очистка HTML в библиотеке Anti-XSS

e.g.

<%= AntiXss.GetSafeHtmlFragment(TempData["message"]) %>
person Charlino    schedule 04.10.2010

Самое простое решение, которое я видел, это:

@MvcHtmlString.Create(Html.Encode(TempData["message"]).Replace(Environment.NewLine, "<br />"))

Если вы используете представление бритвы, вам не нужно обычно вызывать Html.Encode. По умолчанию Razor html кодирует весь вывод. Из блога Скотта Гу, посвященного Razor:

По умолчанию содержимое, создаваемое с помощью блока @, автоматически кодируется в формате HTML для лучшей защиты от сценариев XSS-атак.

person ICodeForCoffee    schedule 21.07.2011

К вашему сведению, разработчики Microsoft Web Protection Library (также известной как Microsoft AntiXSS Library), похоже, сломали сборку и удалили все предыдущие работающие версии. Это уже не жизнеспособное решение в его нынешнем состоянии. Я смотрел на это как на решение этой проблемы, прежде чем читать комментарии. Все 18 текущих оценок последнего выпуска отрицательные и жалуются на то, что он сломан без обновлений от разработчиков, поэтому я даже не пробовал.

Я выбрал решение @ICodeForCoffee, так как использую Razor. Это просто и, кажется, работает довольно хорошо. Мне нужно было взять потенциально длинные описания с разрывами строк и отформатировать их так, чтобы разрывы строк отображались на странице.

Просто для полноты вот код, который я использовал, который представляет собой код @ICodeForCoffee, модифицированный для использования поля описания модели представления:

@MvcHtmlString.Create(Html.Encode(Model.Description).Replace(Environment.NewLine, "<br />"))
person TheUO    schedule 24.08.2012
comment
Согласитесь, это позор, но библиотека XSS теперь практически бесполезна. - person RemarkLima; 29.05.2013

«Обработать» сообщение в контроллере:

  1. HTMLКодировать сообщение
  2. Вставьте теги разрыва строки
  3. Добавьте сообщение в коллекцию TempData.
person Dave Swersky    schedule 04.10.2010
comment
Я думаю, что лучше закодировать сообщение в представлении. Я думаю, что кодирование в контроллере рискованно, так как вы должны убедиться, что делаете это везде, где перенаправляется на действие Index. Легче забыть одно место. - person KallDrexx; 05.10.2010

Попробуй это:

StringBuilder sb = new StringBuilder();

foreach(string message in messages)
{
sb.Append(string.Format("{0}<br />", Server.HtmlEncode(message));
}

TempData["message"] = sb.ToString();
person Andy Evans    schedule 04.10.2010