Izinkan Pengguna untuk memasukkan HTML di ASP.NET MVC - ValidateInput atau AllowHtml

120

Bagaimana cara mengizinkan pengguna untuk memasukkan HTML ke dalam bidang tertentu menggunakan ASP.net MVC.

Saya memiliki formulir panjang dengan banyak bidang yang dipetakan ke objek kompleks ini di pengontrol.

Saya ingin membuat satu bidang (deskripsi) memungkinkan HTML yang akan saya bentuk sebelumnya pada sanitasi saya di lain waktu.

Rabbi
sumber
3
Untuk pengunjung mendatang: Jawaban IMHO, Chris J, atau Eugene Bosikov lebih baik daripada jawaban yang diterima untuk versi ASP.NET MVC yang lebih baru, terutama jika Anda hanya ingin mengizinkan HTML dalam satu bidang.
lc.

Jawaban:

163

Tambahkan atribut berikut tindakan (post) di pengontrol yang Anda ingin izinkan HTML untuk:

[ValidateInput(false)] 

Edit: Sesuai komentar Charlino :

Di web.config Anda, atur mode validasi yang digunakan. Lihat MSDN :

<httpRuntime requestValidationMode="2.0" />

Edit September 2014: Sesuai sprinter, 252 komentar:

Anda sekarang harus menggunakan [AllowHtml]atribut tersebut. Lihat di bawah dari MSDN :

Untuk aplikasi ASP.NET MVC 3, saat Anda perlu memposting HTML kembali ke model Anda, jangan gunakan ValidateInput (false) untuk menonaktifkan Request Validation. Cukup tambahkan [AllowHtml] ke properti model Anda, seperti:

public class BlogEntry {
    public int UserId {get;set;}
    [AllowHtml] 
    public string BlogText {get;set;}
 }
Kelsey
sumber
1
Jika Anda menggunakan .NET 4 Anda juga harus mengaturnya <httpRuntime requestValidationMode="2.0" />di file web.config Anda.
Charlino
3
Apakah benar-benar tidak ada solusi untuk .NET 4 yang tidak menyertakan penurunan mode validasi permintaan?
bzlm
20
MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ) mengatakan, bahwa Anda tidak boleh menggunakan ValidateInpute dan mengambil AllowHtmlAttribute sebagai gantinya. (Tidak menemukan versi bahasa Inggrisnya)
Alexander Schmidt
8
Diedit untuk semoga mengatasi 3 suara negatif yang baru-baru ini dibuat ... itu adalah jawaban berusia 4 tahun :)
Kelsey
1
@ djack109 Biasanya, Anda tidak menggunakan model EF sebagai model tampilan Anda. Anda akan menulis kelas terpisah yang mewakili data aktual untuk operasi CRUD Anda. Dengan cara ini, saat model EF6 Anda dibuat ulang, tidak ada yang hilang. Anda juga harus merampingkan model agar hanya memiliki properti yang Anda perlukan untuk melakukan tugas yang sedang dikerjakan.
Allen Clark Copeland Jr
131

Bagaimana dengan [AllowHtml]atribut di atas properti?

menangis
sumber
5
Ini sepertinya cara yang jauh lebih baik bagi saya, menghindari perubahan perilaku global apa pun. Saya baru saja memecahkan masalah saya dengan menambahkan atribut ini ke properti pada model saya.
Jonathan Sayce
2
Sepenuhnya setuju dengan solusi Chris di sini, tidak ada alasan untuk menonaktifkan validasi html untuk seluruh aplikasi jika Anda hanya memerlukan satu properti dalam model agar dapat menerima input html. Menghapus validasi di web.config akan membuka lubang keamanan besar di aplikasi Anda.
Miguel
1
Sayangnya ini tidak berfungsi jika Anda menggunakan MetadataTypeAttribute
dav_i
@dav_i: Solusi ini berfungsi dengan baik MetadataTypeAttributedan lebih disukai karena hanya mengizinkan HTML pada bidang individu daripada seluruh objek.
Gone Coding
@TrueBlueAussie, saya telah mencoba berjam-jam di lingkungan MVC 4.0 saya dan meskipun AllowHtml seharusnya berfungsi, itu tidak berhasil. Saya harus mengakui kekalahan dan memilih opsi yang kurang aman yaitu celana. AllowHtml sepertinya tidak bekerja dengan penggunaan MetadataTypeAttribute
julian guppy
42

Tambahkan ke model:

using System.Web.Mvc;

Dan untuk properti Anda

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

Kode ini dari poin saya cara terbaik menghindari kesalahan ini. Jika Anda menggunakan editor HTML Anda tidak akan mengalami masalah keamanan karena sudah dibatasi.

Eugene Bosikov
sumber
9

Menambahkan [AllowHtml]pada properti tertentu adalah solusi yang disarankan karena ada banyak blog dan komentar yang menyarankan untuk menurunkan tingkat keamanan, yang seharusnya tidak dapat diterima.

Dengan menambahkan itu, kerangka kerja MVC akan memungkinkan Kontroler untuk dipukul dan kode dalam kontroler itu akan dieksekusi.

Namun, ini tergantung pada kode Anda, filter, dll., Bagaimana respons dibuat dan apakah ada validasi lebih lanjut yang mungkin memicu kesalahan serupa lainnya.

Bagaimanapun, menambahkan [AllowHtml]atribut adalah jawaban yang tepat, karena memungkinkan html untuk dideserialisasi di pengontrol. Contoh di viewmodel Anda:

[AllowHtml]
public string MessageWithHtml {get; set;}
diegosasw
sumber
8

Saya menghadapi masalah yang sama meskipun saya menambahkan [System.Web.Mvc.AllowHtml]ke properti terkait seperti yang dijelaskan dalam beberapa jawaban.

Dalam kasus saya, saya memiliki UnhandledExceptionFilterkelas yang mengakses objek Permintaan sebelum validasi MVC berlangsung (dan karena itu AllowHtml tidak berpengaruh) dan akses ini menimbulkan a [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

Ini berarti, mengakses properti tertentu dari objek Request secara implisit mengaktifkan validasi (dalam kasus saya ini adalah Paramspropertinya).

Solusi untuk mencegah validasi didokumentasikan di MSDN

Untuk menonaktifkan validasi permintaan untuk bidang tertentu dalam permintaan (misalnya, untuk elemen masukan atau nilai string kueri), panggil metode Request.Unvalidated saat Anda mendapatkan item, seperti yang ditunjukkan pada contoh berikut

Oleh karena itu, jika Anda memiliki kode seperti ini

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

ubah menjadi

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

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

atau cukup gunakan Formproperti yang tampaknya tidak mengaktifkan validasi

var lForm = aRequestContext.HttpContext.Request.Form;
if (lForm.Count > 0)
{
  ...
ViRuSTriNiTy
sumber
1
Terima kasih! Request.Unvalidated adalah satu-satunya solusi yang berhasil untuk saya.
Petter Ivarsson
3

Jika Anda perlu mengizinkan masukan html untuk parameter metode tindakan (berlawanan dengan "properti model"), tidak ada cara bawaan untuk melakukannya, tetapi Anda dapat dengan mudah melakukannya menggunakan pengikat model khusus:

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

Kode 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
    }
}

Temukan source code lengkapnya dan penjelasannya di postingan blog saya: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/

Alex
sumber
1
Sepertinya belum divalidasi hanya tersedia dalam kerangka 4.5 ke atas.
Ben
@Ben benar! Silakan periksa solusi yang dimodifikasi ini. stackoverflow.com/questions/59483284/…
om-ha
3

URL Encoding data bekerja dengan baik untuk saya

Sebagai contoh

var data = '<b> Halo </b>'

Dalam panggilan browser encodeURIComponent (data) sebelum posting

Pada panggilan Server HttpUtility.UrlDecode (accept_data) untuk memecahkan kode

Dengan begitu Anda dapat mengontrol dengan tepat area bidang mana yang diizinkan untuk memiliki html

smjhunt
sumber
cara termudah sejauh ini
N1gthm4r3
1

Saya telah menghadapi masalah ini selama pengembangan situs E-Commerce menggunakan NopCommerce, saya mendapatkan solusi ini dengan 3 cara berbeda seperti jawaban sebelumnya. Tetapi menurut struktur NopCommerce, saya tidak menemukan ketiganya sekaligus. Saya baru saja melihat bahwa di sana mereka hanya menggunakan [AllowHtml]dan berfungsi dengan baik kecuali ada masalah. Seperti yang ditanyakan sebelumnya pertanyaan yang

Secara pribadi saya tidak lebih suka [ValidateInput(false)]karena saya melewatkan pemeriksaan entitas model total, yang tidak aman. Tetapi jika ada yang baru saja menulis, lihat di sini

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

maka itu hanya melewatkan satu properti saja, dan hanya mengizinkan hanya properti tertentu dan memeriksa hampir semua entitas lainnya. Oleh karena itu tampaknya lebih disukai daripada milik saya.

gdmanandamohon
sumber
1

Dalam kasus saya, atribut AllowHtml tidak berfungsi saat digabungkan dengan filter tindakan OutputCache. Jawaban ini memecahkan masalah saya. Semoga ini bisa membantu seseorang.

jd4w9.dll
sumber
1

Anda Dapat Menggunakan [AllowHtml]Untuk Proyek Anda Sebagai Contoh

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

Untuk Menggunakan Kode Ini Ke Perpustakaan Kelas Anda Menginstal Paket Ini

Install-Package Microsoft.AspNet.Mvc

Setelah Gunakan Ini using

using System.Web.Mvc;
Diako Hasani
sumber
0

Sayangnya, tidak ada jawaban di sini yang berhasil untuk saya.

Saya akhirnya menggunakan Custom Model Binding dan menggunakan Sanitizer pihak ketiga.

Lihat pertanyaan yang saya jawab sendiri di sini .

om-ha
sumber