programing

CheckBoxFor가 추가 입력 태그를 렌더링하는 이유는 무엇이며 FormCollection을 사용하여 값을 얻는 방법은 무엇입니까?

telebox 2023. 6. 6. 08:12
반응형

CheckBoxFor가 추가 입력 태그를 렌더링하는 이유는 무엇이며 FormCollection을 사용하여 값을 얻는 방법은 무엇입니까?

ASP.NET MVC 앱에서 다음 코드를 사용하여 확인란을 렌더링합니다.

<%= Html.CheckBoxFor(i=>i.ReceiveRSVPNotifications) %>

이제 확인란 입력 태그와 숨겨진 입력 태그를 모두 렌더링합니다.FormCollection을 사용하여 확인란에서 값을 검색하려고 할 때 문제가 발생합니다.

FormValues["ReceiveRSVPNotifications"]

저는 "true, false"라는 값을 얻습니다.렌더링된 HTML을 보면 다음을 볼 수 있습니다.

 <input id="ReceiveRSVPNotifications" name="ReceiveRSVPNotifications" value="true" type="checkbox">
 <input name="ReceiveRSVPNotifications" value="false" type="hidden">

따라서 FormValues 컬렉션은 동일한 이름을 가지고 있기 때문에 이 두 값을 결합하는 것으로 보입니다.

아이디어가 있습니까?

여기를 보십시오.

http://forums.asp.net/t/1314753.aspx

이것은 버그가 아니며, 사실 Ruby on Rails와 MonoRail이 사용하는 것과 동일한 접근 방식입니다.

확인란이 있는 양식을 제출할 때 이 확인란이 선택된 경우에만 값이 게시됩니다.따라서 확인란을 선택하지 않은 상태로 두면 대부분의 경우 거짓을 대신 보내려고 할 때 서버로 아무것도 전송되지 않습니다.숨겨진 입력의 이름이 확인란과 같기 때문에 확인란을 선택하지 않은 경우에도 서버에 'false'가 전송됩니다.

이 확인란을 선택하면 모델 바인더가 자동으로 '참, 거짓'에서 '참'을 추출합니다.

저도 Shawn(위)과 같은 문제가 있었습니다.이 접근 방식은 POST에는 좋을 수 있지만 GET에게는 정말 최악입니다.그래서 저는 숨겨진 필드를 지우는 간단한 Html 확장을 구현했습니다.

public static MvcHtmlString BasicCheckBoxFor<T>(this HtmlHelper<T> html, 
                                                Expression<Func<T, bool>> expression,
                                                object htmlAttributes = null)
{
    var result = html.CheckBoxFor(expression).ToString();
    const string pattern = @"<input name=""[^""]+"" type=""hidden"" value=""false"" />";
    var single = Regex.Replace(result, pattern, "");
    return MvcHtmlString.Create(single);
}

제가 지금 가지고 있는 문제는 제 코드를 깨기 위해 MVC 프레임워크를 변경하는 것을 원하지 않는다는 것입니다.그래서 저는 이 새로운 계약을 설명하는 시험 범위를 확보해야 합니다.

다음과 같은 대체 방법을 사용하여 GET 양식의 확인란을 렌더링합니다.

/// <summary>
/// Renders checkbox as one input (normal Html.CheckBoxFor renders two inputs: checkbox and hidden)
/// </summary>
public static MvcHtmlString BasicCheckBoxFor<T>(this HtmlHelper<T> html, Expression<Func<T, bool>> expression, object htmlAttributes = null)
{
    var tag = new TagBuilder("input");

    tag.Attributes["type"] = "checkbox";
    tag.Attributes["id"] = html.IdFor(expression).ToString();
    tag.Attributes["name"] = html.NameFor(expression).ToString();
    tag.Attributes["value"] = "true";

    // set the "checked" attribute if true
    ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    if (metadata.Model != null)
    {
        bool modelChecked;
        if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked))
        {
            if (modelChecked)
            {
                tag.Attributes["checked"] = "checked";
            }
        }
    }

    // merge custom attributes
    tag.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));

    var tagString = tag.ToString(TagRenderMode.SelfClosing);
    return MvcHtmlString.Create(tagString);
}

크리스 켐프의 방법과 비슷한데, 이 방법은 기본적인 것을 사용하지 않는다는 것을 제외하고는 잘 작동합니다.CheckBoxFor그리고.Regex.Replace원본의 출처를 바탕으로 한 것입니다.Html.CheckBoxFor방법.

가장 간단한 해결책은 다음과 같이 INPUT 요소를 직접 렌더링하는 것이라고 생각합니다.

<input type="checkbox" 
       id="<%=Html.IdFor(i => i.ReceiveRSVPNotifications)%>"
       name="<%=Html.NameFor(i => i.ReceiveRSVPNotifications)%>"
       value="true"
       checked="<%=Model.ReceiveRSVPNotifications ? "checked" : String.Empty %>" />

Razor 구문에서는 '참' 서버 측 값이 주어졌을 때 '체크됨' 특성이 '체크됨' 값으로 직접 렌더링되기 때문에 훨씬 더 쉽습니다.

다음은 추가 입력 태그의 소스 코드입니다.마이크로소프트는 친절하게도 이것을 정확하게 다루는 논평을 포함시켰습니다.

if (inputType == InputType.CheckBox)
{
    // Render an additional <input type="hidden".../> for checkboxes. This
    // addresses scenarios where unchecked checkboxes are not sent in the request.
    // Sending a hidden input makes it possible to know that the checkbox was present
    // on the page when the request was submitted.
    StringBuilder inputItemBuilder = new StringBuilder();
    inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));

    TagBuilder hiddenInput = new TagBuilder("input");
    hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
    hiddenInput.MergeAttribute("name", fullName);
    hiddenInput.MergeAttribute("value", "false");
    inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));
    return MvcHtmlString.Create(inputItemBuilder.ToString());
}

언급URL : https://stackoverflow.com/questions/2860940/why-does-the-checkboxfor-render-an-additional-input-tag-and-how-can-i-get-the-v

반응형