web-dev-qa-db-ja.com

Razor MVC3を使用した条件付きHTML属性

変数strCSSClassにはしばしば値がありますが、空の場合もあります。

この入力要素のHTMLに空のclass = ""を含めたくありません。つまり、strCSSClassが空の場合、class =属性はまったく必要ありません。

以下は、条件付きHTML属性を実行する1つの方法です。

<input type="text" id="@strElementID" @(CSSClass.IsEmpty() ? "" : "class=" + strCSSClass) />

これを行うよりエレガントな方法はありますか?特に、要素の他の部分で使用されているのと同じ構文に従うことができる場所:class = "@ strCSSClass"?

96
tony722

RazorのPMという音は聞こえませんでしたが、Razor 2(Webページ2およびMVC 4)では、条件付き属性がRazorに組み込まれます(MVC 4 RCのテストが成功した時点で) 、このように言うことができます...

<input type="text" id="@strElementID" class="@strCSSClass" />

StrCSSClassがnullの場合、クラス属性はまったくレンダリングされません。

SSSHHH ...言わないで。 :)

155
Erik Porter

次のようなことができることに注意してください(少なくともMVC3では)。

<td align="left" @(isOddRow ? "class=TopBorder" : "style=border:0px") >

かみそりが引用符を追加すると私が信じていたのは、実際にはブラウザでした。 MVC 4でテストするときにRismが指摘したように(MVC 3ではテストしていませんが、動作は変わらないと思います)、これは実際にclass=TopBorderを生成しますが、ブラウザーはこれを解析できます。 HTMLパーサーは、属性引用符の欠落を多少許容しますが、スペースまたは特定の文字がある場合、これは壊れる可能性があります

<td align="left" class="TopBorder" >

OR

<td align="left" style="border:0px" >

あなた自身の引用を提供することで何がうまくいかないか

ネストされた引用符に通常のC#規則を使用しようとすると、Razorが安全にエスケープしようとしているため、予想よりも多くの引用符が表示されます。例えば:

<button type="button" @(true ? "style=\"border:0px\"" : string.Empty)>

このshould<button type="button" style="border:0px">と評価されますが、RazorはC#からのすべての出力をエスケープするため、以下を生成します。

style=&quot;border:0px&quot;

これは、ネットワーク経由で応答を表示する場合にのみ表示されます。 HTMLインスペクタを使用する場合、多くの場合、実際のHTMLではなくDOMが表示されます。ブラウザはHTMLをDOMに解析し、解析後のDOM表現にはすでにいくつかの便利な機能が適用されています。この場合、ブラウザは属性値の前後に引用符がないと判断し、それらを追加します。

style="&quot;border:0px&quot;"

ただし、DOMインスペクターでは、HTML文字コードが適切に表示されるため、実際に表示されます:

style=""border:0px""

Chromeでは、右クリックして[HTMLの編集]を選択すると元に戻り、これらの厄介なHTML文字コードが表示され、実際の外部引用符とHTMLエンコードされた内部引用符が明確になります。

したがって、自分でクォートを実行しようとすると、Razorはこれらをエスケープします。

引用符を完全に制御したい場合

Html.Rawを使用して、引用のエスケープを防ぎます。

<td @Html.Raw( someBoolean ? "rel='tooltip' data-container='.drillDown a'" : "" )>

レンダリング:

<td rel='tooltip' title='Drilldown' data-container='.drillDown a'>

変数からHTMLを出力していないので、上記は完全に安全です。関係する唯一の変数は、三項条件です。ただし、注意この最後の手法では、ユーザーが指定したデータから文字列を作成する場合、特定のセキュリティ問題が発生する可能性があります。例えば。ユーザーが指定したデータから生成されたデータフィールドから属性を作成した場合、Html.Rawを使用すると、文字列に属性とタグの早期終了が含まれることがあり、現在ログインしているユーザーに代わって何かを行うスクリプトタグを開始できます(ログインしているユーザーとは異なる可能性があります)。すべてのユーザーの写真のリストを含むページがあり、ツールチップを各ユーザーのユーザー名に設定している場合、1人のユーザーが自分に'/><script>$.post('changepassword.php?password=123')</script>という名前を付け、このページを表示する他のユーザーのパスワードが即座に変更される場合があります悪意のあるユーザーが知っているパスワードに。

118
AaronLS

もう少し便利で構造化された方法は、Htmlヘルパーを使用することです。ビューでは、次のようになります。

@{
 var htmlAttr = new Dictionary<string, object>();
 htmlAttr.Add("id", strElementId);
 if (!CSSClass.IsEmpty())
 {
   htmlAttr.Add("class", strCSSClass);
 }
}

@* ... *@

@Html.TextBox("somename", "", htmlAttr)

この方法が役立つ場合は、モデルに辞書htmlAttrを定義して、ビューに@{ }論理ブロックが必要ないようにすることをお勧めします(より明確に)。

11
Yaschur