Дозволити користувачеві вводити HTML в ASP.NET MVC - ValidateInput або AllowHtml


120

Як можна дозволити користувачеві вводити HTML у певне поле за допомогою ASP.net MVC.

У мене довга форма з безліччю полів, які відображаються в цьому контролері на складному об'єкті.

Я хотів би зробити одне поле (опис), що дозволить HTML, на якому я згодом підготую власну санітарію.


3
Для майбутніх відвідувачів: відповіді ІМХО, Кріса Дж або Євгена Босикова краще, ніж прийняті для пізніших версій ASP.NET MVC, особливо якщо ви хочете дозволити HTML лише в одному полі.
лк.

Відповіді:


163

Додайте наступний атрибут дії (публікації) у контролер, для якого потрібно дозволити HTML:

[ValidateInput(false)] 

Редагувати: Відповідно до коментарів Чарліно :

У своєму web.config встановіть використаний режим перевірки. Дивіться MSDN :

<httpRuntime requestValidationMode="2.0" />

Редагувати вересень 2014 року: Відповідно до sprinter252 коментарів:

Тепер вам слід використовувати [AllowHtml]атрибут. Дивіться нижче від MSDN :

Для програм ASP.NET MVC 3, коли вам потрібно опублікувати HTML у своїй моделі, не використовуйте ValidateInput (помилковий), щоб вимкнути запит на перевірку. Просто додайте [AllowHtml] у властивість своєї моделі, наприклад:

public class BlogEntry {
    public int UserId {get;set;}
    [AllowHtml] 
    public string BlogText {get;set;}
 }

1
Якщо ви використовуєте .NET 4, вам також доведеться встановити <httpRuntime requestValidationMode="2.0" />у своєму файлі web.config.
Чарліно

3
Чи дійсно немає рішення для .NET 4, яке не включає пониження режиму перевірки запиту?
bzlm

20
MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ) говорить, що не слід використовувати ValidateInpute, а замість цього приймати AllowHtmlAttribute. (Did'nt знайшов англійську версію)
Alexander Schmidt

8
Внесено до редагування, щоб сподіватися на 3 голоси, які були нещодавно внесені ... це було 4-річну відповідь :)
Келсі

1
@ djack109 Як правило, ви не використовуєте модель EF як модель перегляду. Ви б написали окремий клас, який представляє фактичні дані для ваших CRUD-операцій. Таким чином, коли ваша модель EF6 відновлюється, нічого не втрачається. Ви також повинні зменшити вниз моделі, щоб мати лише ті властивості, які вам потрібні для виконання завдання.
Аллен Кларк Коупленд-молодший

131

Що з [AllowHtml]атрибутом вище властивості?


5
Це здається мені набагато кращим способом, уникаючи зміни будь-якої глобальної поведінки. Я щойно вирішив свою проблему, додавши цей атрибут до властивості на моїй моделі.
Джонатан Сайс

2
Повністю згоден з рішенням Криса тут, немає ніяких причин відключати перевірку html для всієї програми, якщо вам потрібно лише одне властивість в моделі, щоб мати змогу приймати html-введення. Видалення перевірки в web.config відкриє велику дірку в безпеці у вашій програмі.
Мігель

1
На жаль, це не працює, якщо ви використовуєте MetadataTypeAttribute
dav_i

@dav_i: Це рішення чудово працює MetadataTypeAttributeі є кращим, оскільки воно дозволяє лише HTML на окремих полях, а не на весь об'єкт.
Пройшов кодування

@TrueBlueAussie, я намагаюся годинами в моєму середовищі mvc 4.0, і хоча AllowHtml повинен працювати це не так. Мені довелося визнати поразку і піти з менш безпечним варіантом - штани. AllowHtml просто не працює з використанням MetadataTypeAttribute
julian guppy

42

Додати в модель:

using System.Web.Mvc;

І до вашого майна

        [AllowHtml]
        [Display(Name = "Body")]
        public String Body { get; set; }

Цей код з моєї точки зору найкращий спосіб уникнути цієї помилки. Якщо ви використовуєте редактор HTML, у вас не виникне проблем із безпекою, оскільки це вже обмежено.


9

Додавання [AllowHtml]конкретної властивості є рекомендованим рішенням, оскільки є багато блогів та коментарів, що дозволяють зменшити рівень безпеки, що має бути неприйнятним.

Додавши це, рамка MVC дозволить звернутись до контролера та виконувати код у цьому контролері.

Однак це залежить від вашого коду, фільтрів тощо, як генерується відповідь та чи є додаткова перевірка, яка може викликати ще одну подібну помилку.

У будь-якому випадку додавання [AllowHtml]атрибута - це правильна відповідь, оскільки дозволяє десеріалізувати html в контролері. Приклад у вашій моделі перегляду:

[AllowHtml]
public string MessageWithHtml {get; set;}

8

Я зіткнувся з тим же питанням, хоча я додав [System.Web.Mvc.AllowHtml]відповідне майно, як описано в деяких відповідях.

У моєму випадку у мене є UnhandledExceptionFilterклас, який звертається до об'єкта Request до того, як відбудеться перевірка MVC (і тому AllowHtml не має ефекту), і цей доступ підвищує a [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

Це означає, що доступ до певних властивостей об'єкта Request неявно запускає перевірку (у моєму випадку його Paramsвластивість).

Рішення для запобігання валідації задокументоване на MSDN

Щоб відключити перевірку запиту для певного поля в запиті (наприклад, для вхідного елемента або значення рядка запиту), зателефонуйте метод Request.Uvavalified, коли ви отримаєте елемент, як показано в наступному прикладі

Тому, якщо у вас є такий код

var lParams = aRequestContext.HttpContext.Request.Params;
if (lParams.Count > 0)
{
  ...

змінити його на

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

var lForm = lUnvalidatedRequest.Form;
if (lForm.Count > 0)
{
  ...

або просто використовувати Formмайно, яке, здається, не спрацьовує

var lForm = aRequestContext.HttpContext.Request.Form;
if (lForm.Count > 0)
{
  ...

1
Дякую! Request.Uvavalified було єдиним рішенням, яке працювало для мене.
Петтер Іварссон

3

Якщо вам потрібно дозволити введення html для параметра методу дії (на відміну від "властивості моделі"), немає вбудованого способу зробити це, але ви можете легко досягти цього, використовуючи прив'язку власної моделі:

public ActionResult AddBlogPost(int userId,
    [ModelBinder(typeof(AllowHtmlBinder))] string htmlBody)
{
    //...
}

Код AllowHtmlBinder:

public class AllowHtmlBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;
        var name = bindingContext.ModelName;
        return request.Unvalidated[name]; //magic happens here
    }
}

Знайдіть повний вихідний код та пояснення в моєму дописі в блозі: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/


1
Здається, недійсна інформація доступна лише в рамках 4.5 і вище.
Бен

@Бен правильно! Перевірте це змінене рішення. stackoverflow.com/questions/59483284/…
ом-ха

3

Кодування URL-адрес для мене також працює

Наприклад

var data = '<b> Привіт </b>'

У кодуванні виклику браузераURIComponent (дані) перед публікацією

На сервері викликайте HttpUtility.UrlDecode (отримані_дані) для декодування

Таким чином ви можете точно контролювати, в якій області полів дозволено мати HTML


найпростіший спосіб поки
N1gthm4r3

1

Я зіткнувся з цією проблемою під час розробки сайту електронної комерції за допомогою NopCommerce, я отримав це рішення трьома різними способами, як і попередні відповіді. Але за структурою NopCommerce я цих трьох не знайшов одночасно. Я щойно бачив, що там вони користуються просто, [AllowHtml]і це працює нормально, крім будь-якої проблеми. Як раніше задавали питання

Особисто я не віддаю перевагу, [ValidateInput(false)]тому що я пропускаю загальну перевірку сутності моделі, що є небезпечним. Але якщо хтось просто пише , подивіться тут

[AllowHtml] 
public string BlogText {get;set;}

тоді він просто пропускає лише одну власність, а також дозволяє лише окреме майно та перевіряє навряд чи всі інші об'єкти. Тому це здається кращим щодо мого.


1

У моєму випадку атрибут AllowHtml не працював у поєднанні з фільтром дій OutputCache. Ця відповідь вирішила проблему для мене. Сподіваюся, що це комусь допоможе.


1

Ви можете використовувати [AllowHtml]для свого проекту, наприклад

 [AllowHtml]
 public string Description { get; set; }

Для використання цього коду для бібліотеки класів ви встановлюєте цей пакет

Install-Package Microsoft.AspNet.Mvc

Після використання цього using

using System.Web.Mvc;

0

Жодна відповідь тут не працювала для мене, на жаль.

Я в кінцевому підсумку використовував власні моделі прив'язки та використовував сторонній Sanitizer.

Дивіться моє запитання із самовідповіддю тут .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.