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를 보내려고 할 때 서버로 아무것도 보내지 않습니다. 숨겨진 입력은 확인란과 이름이 같으므로 확인란이 선택되어 있지 않으면 여전히 서버에 'false'가 전송됩니다.
확인란을 선택하면 ModelBinder가 자동으로 'true, false'에서 'true'를 추출합니다.
나는 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
방법 의 출처를 기반으로합니다 .
추가 입력 태그 의 소스 코드는 다음과 같습니다 . Microsoft는이 문제를 정확하게 해결하는 의견을 포함시킬만큼 친절했습니다.
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());
}
가장 간단한 해결책은 다음과 같이 INPUT 요소를 직접 렌더링하는 것입니다.
<input type="checkbox"
id="<%=Html.IdFor(i => i.ReceiveRSVPNotifications)%>"
name="<%=Html.NameFor(i => i.ReceiveRSVPNotifications)%>"
value="true"
checked="<%=Model.ReceiveRSVPNotifications ? "checked" : String.Empty %>" />
In Razor syntax it is even easier, because the 'checked' attribute is directly rendered with a "checked" value when given a 'true' server-side value.
'Programming' 카테고리의 다른 글
이메일을 보내는 앱을 개발하고 테스트하는 방법 (테스트 데이터로 다른 사람의 사서함을 채우지 않고)? (0) | 2020.07.03 |
---|---|
HttpURLConnection에서 PUT, DELETE HTTP 요청을 보내는 방법은 무엇입니까? (0) | 2020.07.03 |
pem 키를 ssh-rsa 형식으로 변환 (0) | 2020.07.03 |
SVN 업그레이드 작업 사본 (0) | 2020.07.03 |
JPA @Column 주석을 참조하여 insertable = false 및 updatable = false에 대해 설명하십시오. (0) | 2020.07.03 |