Разрешить пользователю вводить HTML в ASP.NET MVC - ValidateInput или AllowHtml


120

Как я могу разрешить пользователю вводить HTML в определенное поле с помощью ASP.net MVC.

У меня есть длинная форма со множеством полей, которые сопоставляются с этим сложным объектом в контроллере.

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


3
Для будущих посетителей: IMHO, ответы Криса Дж. Или Евгения Босикова лучше, чем принятый для более поздних версий ASP.NET MVC, особенно если вы хотите разрешить HTML только в одном поле.
lc.

Ответы:


163

Добавьте следующий атрибут action (post) в контроллер, для которого вы хотите разрешить HTML:

[ValidateInput(false)] 

Изменить: согласно комментариям Чарлино :

В вашем web.config установите используемый режим проверки. См. MSDN :

<httpRuntime requestValidationMode="2.0" />

Изменить сентябрь 2014 г .: Согласно комментариям sprinter252 :

Теперь вы должны использовать [AllowHtml]атрибут. См. Ниже из MSDN :

Для приложений ASP.NET MVC 3, когда вам нужно отправить HTML обратно в модель, не используйте ValidateInput (false) для отключения проверки запроса. Просто добавьте [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 02

20
MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ) говорит, что вам не следует использовать ValidateInpute и вместо этого использовать AllowHtmlAttribute. (Не нашел английскую версию)
Александр Шмидт

8
Сделано редактирование, чтобы, надеюсь, ответить на 3 голоса против, которые были недавно сделаны ... это был ответ 4-летней давности :)
Келси

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

131

А как насчет [AllowHtml]атрибута над свойством?


5
Мне кажется, что это намного лучший способ избежать изменения глобального поведения. Я только что решил свою проблему, добавив этот атрибут в свойство моей модели.
Джонатан Сэйс

2
Полностью согласен с решением Криса, нет причин отключать проверку html для всего приложения, если вам просто нужно одно свойство в модели, чтобы иметь возможность принимать ввод html. Удаление проверки в web.config откроет большую дыру в безопасности вашего приложения.
Мигель

1
К сожалению, это не работает, если вы используете MetadataTypeAttribute
dav_i

@dav_i: это решение отлично работает MetadataTypeAttributeи является предпочтительным, поскольку оно позволяет использовать HTML только для отдельных полей, а не для всего объекта.
Gone Coding

@TrueBlueAussie, я часами пытался в своей среде mvc 4.0, и хотя AllowHtml должен работать, это не так. Мне пришлось признать поражение и выбрать менее безопасный вариант - штаны. AllowHtml, похоже, не работает с использованием MetadataTypeAttribute
джулиан гуппи

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 не действует), и этот доступ вызывает файл [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

Это означает, что доступ к определенным свойствам объекта Request неявно запускает проверку (в моем случае это Paramsсвойство).

Решение для предотвращения проверки задокументировано в MSDN.

Чтобы отключить проверку запроса для определенного поля в запросе (например, для входного элемента или значения строки запроса), вызовите метод Request.Unvalidated при получении элемента, как показано в следующем примере

Поэтому, если у вас есть такой код

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.Unvalidated был единственным решением, которое сработало для меня.
Петтер Иварссон

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/…
om-ha

3

URL-кодирование данных также работает для меня

Например

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

В браузере вызовите encodeURIComponent (data) перед публикацией

На сервере вызовите HttpUtility.UrlDecode (Received_data) для декодирования

Таким образом вы можете точно контролировать, в какой области полей разрешено иметь html.


самый простой способ
N1gthm4r3

1

Я столкнулся с этой проблемой во время разработки сайта электронной коммерции с использованием NopCommerce, я получил это решение 3 разными способами, как и в предыдущих ответах. Но согласно структуре 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

К сожалению, ни один из ответов здесь не помог мне.

В итоге я использовал Custom Model Binding и сторонний Sanitizer.

См. Мой вопрос с самоответом здесь .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.