Kullanıcının ASP.NET MVC'de HTML girmesine izin ver - ValidateInput veya AllowHtml


120

Bir kullanıcının ASP.net MVC'yi kullanarak belirli bir alana HTML girmesine nasıl izin verebilirim.

Denetleyicideki bu karmaşık nesneye eşlenen birçok alana sahip uzun bir formum var.

Daha sonraki bir noktada kendi temizliğimi önceden şekillendireceğim bir alanın (açıklama) HTML'ye izin vermesini istiyorum.


3
Gelecekteki ziyaretçiler için: IMHO, Chris J veya Eugene Bosikov'un yanıtları, özellikle tek bir alanda HTML'ye izin vermek istiyorsanız, ASP.NET MVC'nin sonraki sürümleri için kabul edilenlerden daha iyidir.
lc.

Yanıtlar:


163

HTML'ye izin vermek istediğiniz denetleyiciye aşağıdaki özniteliği (post) ekleyin:

[ValidateInput(false)] 

Düzenleme: gereğince Charlino yorumlarla:

Web.config dosyanızda kullanılan doğrulama modunu ayarlayın. MSDN'ye bakın :

<httpRuntime requestValidationMode="2.0" />

Düzenleme Eylül 2014: gereğince sprinter252 yorumlarla:

Şimdi [AllowHtml]özniteliği kullanmalısınız . MSDN'den aşağıya bakın :

ASP.NET MVC 3 uygulamaları için, HTML'yi modelinize geri göndermeniz gerektiğinde, İstek Doğrulaması'nı kapatmak için ValidateInput (false) kullanmayın. Model mülkünüze [AllowHtml] eklemeniz yeterlidir, örneğin:

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

1
.NET 4 kullanıyorsanız <httpRuntime requestValidationMode="2.0" />, web.config dosyanıza da ayarlamanız gerekir.
Charlino

3
Gerçekten .NET 4 için istek doğrulama modunu düşürmeyi içermeyen bir çözüm yok mu?
bzlm

20
MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ), ValidateInpute kullanmamanız ve bunun yerine AllowHtmlAttribute kullanmamanız gerektiğini söylüyor. (İngilizce sürümü bulamadı)
Alexander Schmidt

8
Son zamanlarda yapılan 3 olumsuz oyu umarız ele almak için düzenleme yapıldı ... bu 4 yıllık bir cevaptı :)
Kelsey

1
@ djack109 Genellikle, EF modelinizi görünüm modeliniz olarak kullanmazsınız. CRUD işlemleriniz için gerçek verileri temsil eden ayrı bir sınıf yazarsınız. Bu şekilde EF6 modeliniz yeniden oluşturulduğunda hiçbir şey kaybolmaz. Ayrıca, yalnızca elinizdeki görevi gerçekleştirmek için ihtiyaç duyduğunuz özelliklere sahip olmak için modelleri inceltmelisiniz.
Allen Clark Copeland Jr

131

[AllowHtml]Mülkiyetin üzerindeki öznitelik ne olacak ?


5
Bu, benim için herhangi bir küresel davranışı değiştirmekten kaçınmanın çok daha iyi bir yolu gibi görünüyor. Modelimdeki bir mülke bu özelliği ekleyerek sorunumu çözdüm.
Jonathan Sayce

2
Burada Chris çözümüne tamamen katılıyorum, html girişini kabul edebilmek için bir modelde yalnızca bir özelliğe ihtiyacınız varsa, tüm uygulama için html doğrulamasını devre dışı bırakmak için hiçbir neden yoktur. Web.config dosyasındaki doğrulamayı kaldırmak, uygulamanızda büyük bir güvenlik açığı açar.
Miguel


@dav_i: Bu çözüm MetadataTypeAttribute, tüm nesne yerine yalnızca tek tek alanlarda HTML'ye izin verdiği için tercih edilir.
Kodlamaya Gitti

@TrueBlueAussie, mvc 4.0 ortamımda saatlerdir deniyorum ve AllowHtml çalışmasına rağmen çalışmıyor. Yenilgiyi kabul etmek ve daha az güvenli bir seçenek olan pantolonla gitmek zorunda kaldım. AllowHtml MetadataTypeAttribute kullanımıyla çalışmıyor gibi görünüyor
julian lepistes

42

Modele ekle:

using System.Web.Mvc;

Ve mülkünüze

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

Bu kod benim açımdan bu hatayı önlemenin en iyi yolu. HTML düzenleyici kullanıyorsanız, zaten kısıtlanmış olduğundan güvenlik sorunları yaşamazsınız.


9

[AllowHtml]Kabul edilemez olması gereken güvenlik düzeyini düşürmeyi öneren çok sayıda blog ve yorum bulunduğundan, belirli özelliğe eklemek önerilen çözümdür.

Bunu ekleyerek, MVC çerçevesi Denetleyicinin vurulmasına ve denetleyicideki kodun çalıştırılmasına izin verecektir.

Ancak, kodunuza, filtrelerinize, vb. Yanıtın nasıl oluşturulduğuna ve başka bir benzer hatayı tetikleyebilecek başka bir doğrulama olup olmadığına bağlıdır.

Her durumda, [AllowHtml]html'nin denetleyicide serileştirilmesinin kaldırılmasına izin verdiği için öznitelik eklemek doğru yanıttır. Görünüm modelinizdeki örnek:

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

8

[System.Web.Mvc.AllowHtml]Bazı cevaplarda anlatıldığı gibi ilgili mülke eklememe rağmen aynı sorunla karşılaştım .

Benim durumumda, MVC doğrulaması gerçekleşmeden önceUnhandledExceptionFilter Request nesnesine erişen bir sınıfa sahibim (ve bu nedenle AllowHtml etkisizdir) ve bu erişim bir .[HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client

Bu, bir Request nesnesinin belirli özelliklerine erişmenin dolaylı olarak doğrulamayı başlattığı anlamına gelir (benim durumumda, Paramsözelliği).

Doğrulamayı önlemek için bir çözüm MSDN'de belgelenmiştir

Bir istekteki belirli bir alan için istek doğrulamasını devre dışı bırakmak için (örneğin, bir giriş öğesi veya sorgu dizesi değeri için), aşağıdaki örnekte gösterildiği gibi öğeyi aldığınızda Request.Unvalidated yöntemini çağırın

Bu nedenle, böyle bir kodunuz varsa

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

şuna değiştir

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

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

veya sadece Formdoğrulama başlatmıyor gibi görünen mülkü kullanın

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

1
Teşekkürler! Benim için işe yarayan tek çözüm istek geçersiz kılındı.
Petter Ivarsson

3

Eylem yöntemi parametresi için ("model özelliği" nin aksine) html girdisine izin vermeniz gerekiyorsa, bunu yapmanın yerleşik bir yolu yoktur, ancak bunu özel bir model bağlayıcı kullanarak kolayca elde edebilirsiniz:

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

AllowHtmlBinder kodu:

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

Tam kaynak kodunu ve açıklamayı blog yazımda bulun: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/


1
Doğrulanmamış, yalnızca 4.5 ve üzeri çerçevelerde kullanılabilir görünmektedir.
Ben

@ Ben doğru! Lütfen bu değiştirilmiş çözümü kontrol edin. stackoverflow.com/questions/59483284/…
om-ha

3

Verilerin URL Kodlaması benim için de iyi çalışıyor

Örneğin

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

Tarayıcıda, göndermeden önce encodeURIComponent (veri) çağrısı

Sunucuda kodu çözmek için HttpUtility.UrlDecode (alınan_data) çağırın

Bu şekilde tam olarak hangi alanların html'ye sahip olmasına izin verildiğini kontrol edebilirsiniz.


şimdiye kadarki en kolay yol
N1gthm4r3

1

NopCommerce kullanarak bir E-Ticaret sitesi geliştirirken bu sorunla karşılaştım, bu çözümü önceki cevaplarda olduğu gibi 3 farklı yoldan aldım. Ancak NopCommerce yapısına göre bu üçünü aynı anda bulamadım. Orada sadece kullandıklarını [AllowHtml]ve herhangi bir sorun dışında iyi çalıştığını gördüm . Daha önce sorulan soru gibi

Kişisel olarak tercih etmiyorum [ValidateInput(false)]çünkü güvensiz olan toplam model varlık kontrolünü atlıyorum. Ama sadece yazan biri buraya bir göz atarsa

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

o zaman sadece tek bir mülkü atlar ve yalnızca belirli bir mülke izin verir ve hemen hemen tüm diğer varlıkları kontrol eder. Bu nedenle benimkine tercih edilebilir görünüyor.


1

Benim durumumda, AllowHtml özniteliği OutputCache eylem filtresiyle birleştirildiğinde çalışmıyordu. Bu cevap benim için sorunu çözdü. Umarım bu birine yardımcı olur.


1

[AllowHtml]Projenize Örnek Olarak Kullanabilirsiniz

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

Bu Paketi Kurduğunuz Sınıf Kitaplığı İçin Bu Kodu Kullanmak İçin

Install-Package Microsoft.AspNet.Mvc

Bunu Kullandıktan Sonra using

using System.Web.Mvc;

0

Maalesef buradaki cevapların hiçbiri benim için işe yaramadı.

Custom Model Binding'i kullanmayı bıraktım ve üçüncü taraf bir Sanitizer kullandım.

Kendi kendine yanıtladığım sorumu burada görün .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.