ユーザーがASP.NET MVCにHTMLを入力できるようにする-ValidateInputまたはAllowHtml


120

ユーザーがASP.net MVCを使用して特定のフィールドにHTMLを入力できるようにするにはどうすればよいですか。

コントローラのこの複雑なオブジェクトにマッピングされる多くのフィールドを持つ長いフォームがあります。

1つのフィールド(説明)でHTMLを使用できるようにしたいのですが、HTMLは後で独自の衛生管理を行う予定です。


3
今後の訪問者向け:IMHO、Chris J、またはEugene Bosikovの回答は、特に1つのフィールドでHTMLのみを許可する場合、ASP.NET MVCの後のバージョンで受け入れられた回答よりも優れています。
lc。

回答:


163

HTMLを許可するコントローラーに次の属性アクション(投稿)を追加します。

[ValidateInput(false)] 

編集: 1としてCharlinoのコメント:

web.configで、使用する検証モードを設定します。MSDNを参照してください。

<httpRuntime requestValidationMode="2.0" />

2014年9月を編集: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ファイルでも設定する必要があります。
Charlino

3
リクエスト検証モードのダウングレードを含まない.NET 4のソリューションは本当にありませんか?
bzlm

20
MSDN(msdn.microsoft.com/de-de/magazine/hh708755.aspx)は、ValidateInputeを使用して、代わりにAllowHtmlAttributeを取るべきではないと述べています。(英語版は見つかりませんでした)
アレクサンダーシュミット

8
最近行われた3つの反対票にうまく対応できるように編集しました...それは4年前の回答でした:)
Kelsey

1
@ djack109通常、ビューモデルとしてEFモデルを使用しません。CRUD操作の実際のデータを表す別のクラスを作成します。このようにして、EF6モデルを再生成しても、何も失われません。また、モデルをスリム化して、実行中のタスクを実行するために必要なプロパティのみを取得する必要もあります。
アレンクラークコープランドJr

131

[AllowHtml]プロパティの上の属性はどうですか?


5
これは私にとってはるかに良い方法のようで、グローバルな行動を変えることを避けます。この属性をモデルのプロパティに追加することで問題を解決しました。
ジョナサンセイス、2012

2
ここでChrisのソリューションに完全に同意します。HTML入力を受け入れるためにモデル内の1つのプロパティのみが必要な場合は、アプリケーション全体のHTML検証を無効にする理由はありません。web.configの検証を削除すると、アプリに大きなセキュリティホールが開きます。
ミゲル

1
残念ながら、MetadataTypeAttribute
dav_i

@dav_i:このソリューションMetadataTypeAttributeは、オブジェクト全体ではなく個々のフィールドでのみHTMLを許可するため、問題なく機能し、望ましい方法です。
コーディング終了2013

@TrueBlueAussie、私は私のmvc 4.0環境で何時間も試行してきましたが、AllowHtmlは動作するはずですが動作しません。私は敗北を認め、パンツという安全性の低いオプションを使用しなければなりませんでした。AllowHtmlはちょうどdoesntのMetadataTypeAttributeの使用で動作するように思える
ジュリアングッピー

42

モデルに追加:

using System.Web.Mvc;

そしてあなたの財産に

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

私のポイントからのこのコードは、このエラーを回避する最良の方法です。HTMLエディターを使用している場合、既に制限されているため、セキュリティ上の問題はありません。


9

追加 [AllowHtml]特定のプロパティをすることは、許容できないセキュリティレベルを下げることを提案するブログやコメントがたくさんあるため、推奨されるソリューションです。

これを追加することで、MVCフレームワークはコントローラーにヒットし、そのコントローラーのコードを実行できるようにします。

ただし、コードやフィルターなど、応答の生成方法と、別の同様のエラーをトリガーする可能性のある検証があるかどうかによって異なります。

いずれにせよ、[AllowHtml]htmlをコントローラーで逆シリアル化できるため、属性を追加することが正しい答えです。あなたのviewmodelの例:

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

8

[System.Web.Mvc.AllowHtml]いくつかの回答で説明されているように、関連するプロパティに追加しましたが、同じ問題に直面しました。

私の場合、MVC検証が行われる前にUnhandledExceptionFilter Requestオブジェクトアクセスするクラスがあり(したがって、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が私にとって有効な唯一のソリューションでした。
Petter Ivarsson

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
Unvalidatedは、フレームワーク4.5以降でのみ使用できるようです。
ベン

@ベン正解!この修正されたソリューションを確認してください。 stackoverflow.com/questions/59483284/...
OM-haの

3

データのURLエンコードは私にとってもうまくいきます

例えば

var data = '<b>こんにちは</ b>'

ブラウザで、投稿する前にencodeURIComponent(data)を呼び出します

サーバーでHttpUtility.UrlDecode(received_data)を呼び出してデコードします

そうすることで、htmlを許可するフィールド領域を正確に制御できます


これまでで最も簡単な方法
N1gthm4r3

1

私はNopCommerceを使用したeコマースサイトの開発中にこの問題に直面しました。以前の回答と同様に、3つの異なる方法でこのソリューションを得ました。しかし、NopCommerceの構造によれば、これら3つは一度に見つかりませんでした。私はちょうど彼らがちょうど[AllowHtml]それを使用しているところを見ただけであり、それはどんな問題を除いてうまく機能しています。以前に質問されたとおり

個人的には[ValidateInput(false)]、モデルエンティティ全体のチェックをスキップしているので、これは安全ではありません。しかし、誰かがここに書いたら、ここを見てください

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

次に、単一のプロパティのみをスキップし、特定のプロパティのみを許可して、他のすべてのエンティティをほとんどチェックしません。したがって、私の方が望ましいようです。


1

私の場合、OutputCacheアクションフィルターと組み合わせると、AllowHtml属性が機能しませんでした。この答えは私にとって問題を解決しました。これが誰かを助けることを願っています。


1

[AllowHtml]たとえば、プロジェクトで使用できます

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

このコードをクラスライブラリに使用するには、このパッケージをインストールしてください

Install-Package Microsoft.AspNet.Mvc

これを使用した後 using

using System.Web.Mvc;

0

残念ながら、ここでの答えはどれもうまくいきませんでした。

最終的にカスタムモデルバインディングを使用し、サードパーティのSanitizerを使用しました。

こちらの私の自己回答の質問をご覧ください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.