[html] Razor MVC3를 사용하는 조건부 HTML 속성

변수 strCSSClass는 종종 값을 갖지만 때로는 비어 있습니다.

이 입력 요소의 HTML에 빈 class = “”를 포함하고 싶지 않습니다. 즉, strCSSClass가 비어 있으면 class = 속성이 전혀 필요하지 않습니다.

다음은 조건부 HTML 속성을 수행하는 한 가지 방법입니다.

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

이 작업을 수행하는 더 우아한 방법이 있습니까? 특히 요소의 다른 부분에서 사용되는 것과 동일한 구문을 따를 수있는 경우 : class = “@ strCSSClass”?



답변

Razor의 PM 인 저 에게서는 듣지 못했지만 Razor 2 (웹 페이지 2 및 MVC 4)에서는 Razor에 조건부 속성이 내장되어 있습니다 (MVC 4 RC가 성공적으로 테스트 됨). 이런거 …

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

strCSSClass가 null이면 클래스 속성이 전혀 렌더링되지 않습니다.

SSSHHH … 말 하지마. 🙂


답변

다음과 같이 할 수 있습니다 (최소한 MVC3에서는).

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

내가 따옴표를 추가하는 면도칼이라고 생각한 것은 실제로 브라우저였습니다. Rism이 MVC 4로 테스트 할 때 지적했듯이 (MVC 3로 테스트하지는 않았지만 동작이 변경되지 않았다고 가정합니다) 이것은 실제로 생성 class=TopBorder되지만 브라우저는 이것을 잘 분석 할 수 있습니다. HTML 파서는 누락 된 속성 따옴표를 다소 용서하지만 공백이나 특정 문자가 있으면 깨질 수 있습니다 .

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

또는

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

자신의 견적을 제공하는 데있어 문제점

중첩 된 따옴표에 대해 일반적인 C # 규칙 중 일부를 사용하려고하면 Razor가 안전하게 이스케이프하려고하기 때문에 따옴표보다 더 많은 따옴표를 사용하게됩니다. 예를 들면 :

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

이것은 해야 으로 평가 <button type="button" style="border:0px">하지만, 면도기는 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를 사용하면 문자열에 속성과 태그의 조기 종료가 포함될 수 있으며 현재 로그인 한 사용자를 대신하여 작업을 수행하는 스크립트 태그를 시작할 수 있습니다. 사용자 (로그인 한 사용자와 다를 수 있음). 모든 사용자 사진 목록이있는 페이지가 있고 각 사용자의 사용자 이름이되는 도구 설명을 설정하고 한 명의 사용자가 자신의 이름을 지을 수 있습니다.'/><script>$.post('changepassword.php?password=123')</script> 이제이 페이지를 보는 다른 사용자는 악의적 인 사용자가 알고있는 암호로 즉시 암호를 변경하게됩니다.


답변

좀 더 편리하고 체계적인 방법은 Html 도우미를 사용하는 것입니다. 보기에서 다음과 같이 보일 수 있습니다.

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

@* ... *@

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

이 방법이 유용 htmlAttr하다면 뷰에 @{ }논리 블록이 필요하지 않도록 모델에 사전을 정의하는 것이 좋습니다 (더 명확하게).


답변