【发布时间】:2015-10-23 01:01:12
【问题描述】:
我正在尝试将此剃须刀代码转换为 C# 代码。但是,复选框回发有问题。
<div class="input-group">
@Html.TextBoxFor(model => model.Property1, new { @class = "form-control js-template-text", data_val = "false" }
<span class="input-group-addon">
@Html.CheckBoxFor(model => model.Property2, new { data_val = "false" })
@Html.HiddenFor(model => model.Property2)
<span class="glyphicon glyphicon-phone glyphicon-green"></span>
</span>
</div>
这部分标记工作得很好。 但是从这个 c# 代码生成的标记没有。两种方法生成的标记是相同的。 我的问题是:代码中需要进行哪些修改(如果有的话),以便浏览器发送正确的复选框值。
private static MvcHtmlString CreateTextBoxCheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, string>> textBoxExpression, Expression<Func<TModel, bool>> checkBoxExpression, IGlyphIcon checkBoxGlyphIcon = null, IDictionary<string, object> htmlAttributes = null, IDictionary<string, object> textBoxHtmlAttributes = null, IDictionary<string, object> checkBoxHtmlAttributes = null)
{
var sb = new StringBuilder();
#region OuterDiv
var outerDivTag = new TagBuilder("div");
outerDivTag.MergeAttributes(htmlAttributes);
outerDivTag.AddCssClass("input-group");
sb.AppendLine(outerDivTag.ToString(TagRenderMode.StartTag));
#endregion OuterDiv
#region TextBox
var textBoxName = ExpressionHelper.GetExpressionText(textBoxExpression);
var textBoxFullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(textBoxName);
var textBoxId = TagBuilder.CreateSanitizedId(textBoxFullName);
var textBoxMetaData = ModelMetadata.FromLambdaExpression(textBoxExpression, htmlHelper.ViewData);
var textBoxValue = textBoxMetaData.Model.ToString();
var textBoxTag = new TagBuilder("input");
textBoxTag.Attributes.Add("type", "text");
textBoxTag.Attributes.Add("class", "form-control");
textBoxTag.Attributes.Add("name", textBoxFullName);
textBoxTag.Attributes.Add("id", textBoxId);
textBoxTag.Attributes.Add("value", textBoxValue);
// get data annotation/client side scripts attributes
var textkBoxValidationAttributes = htmlHelper.GetUnobtrusiveValidationAttributes(textBoxFullName, textBoxMetaData);
foreach (var key in textkBoxValidationAttributes.Keys)
{
textBoxTag.Attributes.Add(key, textkBoxValidationAttributes[key].ToString());
}
textBoxTag.MergeAttributes(textBoxHtmlAttributes, true);
sb.AppendLine(textBoxTag.ToString(TagRenderMode.SelfClosing));
#endregion TextBox
#region CheckBox
var checkBoxSpan = new TagBuilder("span");
checkBoxSpan.Attributes.Add("class", "input-group-addon");
var checkBoxName = ExpressionHelper.GetExpressionText(checkBoxExpression);
var checkBoxFullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(checkBoxName);
var checkBoxId = TagBuilder.CreateSanitizedId(checkBoxFullName);
var checkBoxMetaData = ModelMetadata.FromLambdaExpression(checkBoxExpression, htmlHelper.ViewData);
var checkBoxValue = checkBoxMetaData.Model.ToString().ToLower();
var checkBoxTag = new TagBuilder("input");
checkBoxTag.Attributes.Add("type", "checkbox");
checkBoxTag.Attributes.Add("name", checkBoxFullName);
checkBoxTag.Attributes.Add("id", checkBoxId);
checkBoxTag.Attributes.Add("value", checkBoxValue);
if (checkBoxValue.Equals("true", StringComparison.InvariantCultureIgnoreCase))
{
checkBoxTag.Attributes.Add("checked", "checked");
}
// get data annotation/client side scripts attributes
var validationAttributes = htmlHelper.GetUnobtrusiveValidationAttributes(checkBoxFullName, checkBoxMetaData);
foreach (var key in validationAttributes.Keys)
{
checkBoxTag.Attributes.Add(key, validationAttributes[key].ToString());
}
checkBoxTag.MergeAttributes(checkBoxHtmlAttributes, true);
// to keep track of checkbox postbacks, create hidden input for checkbox
var checkBoxHiddenTag = new TagBuilder("input");
checkBoxHiddenTag.Attributes.Add("name", checkBoxFullName);
checkBoxHiddenTag.Attributes.Add("id", checkBoxId);
checkBoxHiddenTag.Attributes.Add("type", "hidden");
checkBoxHiddenTag.Attributes.Add("value", checkBoxValue.Equals("true", StringComparison.InvariantCultureIgnoreCase) ? "True" : "False");
sb.AppendLine(checkBoxSpan.ToString(TagRenderMode.StartTag));
sb.AppendLine(checkBoxTag.ToString(TagRenderMode.SelfClosing));
sb.AppendLine(checkBoxHiddenTag.ToString(TagRenderMode.SelfClosing));
#endregion CheckBox
#region GlyphIcon
if (checkBoxGlyphIcon != null)
{
var checkBoxGlyphIconSpan = new TagBuilder("span");
checkBoxGlyphIconSpan.Attributes.Add("class", checkBoxGlyphIcon.CssClass);
sb.AppendLine(checkBoxGlyphIconSpan.ToString(TagRenderMode.StartTag));
sb.AppendLine(checkBoxGlyphIconSpan.ToString(TagRenderMode.EndTag));
}
#endregion GlyphIcon
sb.AppendLine(checkBoxSpan.ToString(TagRenderMode.EndTag));
sb.AppendLine(outerDivTag.ToString(TagRenderMode.EndTag));
var result = MvcHtmlString.Create(sb.ToString());
return result;
}
【问题讨论】:
-
你的问题是什么。你有什么问题?
-
你有什么理由不只使用内置扩展而不是尝试重新发明轮子 - 例如。
sb.append(htmlHelper.TextBoxFor(....));等 -
@StephenMuecke,问题是浏览器不使用扩展方法回发复选框值(正确),但它使用剃刀标记。
-
@StephenMuecke 至于为什么不使用现有的框架扩展,首先尝试了,但它以某种方式生成了带有额外字符的标记,从而阻止了表单提交。花了一段时间才弄清楚。
-
我知道,如果初始值为
true,即使您取消选中复选框,它也会始终回复true:)。但是你需要在你的问题中解释问题(不要指望别人猜到问题)。
标签: c# asp.net-mvc