Asp.net mvc 3 MVC3 Razor Html.TextBoxFor:我可以像TextAreaFor那样多行吗?

Asp.net mvc 3 MVC3 Razor Html.TextBoxFor:我可以像TextAreaFor那样多行吗?,asp.net-mvc-3,textbox,razor,textarea,multiline,Asp.net Mvc 3,Textbox,Razor,Textarea,Multiline,我已经看过这篇文章: 但我无法更改为Html.TextAreaFor(),因为它没有一个属性可供我设置动态默认值(我正在创建一个编辑页面,我希望动态填充当前数据的字段,然后可以修改这些字段)。即使我在viewmodel中更改为[DataType(DataType.multilitext)],我似乎也无法让编辑器for工作(它所做的一切似乎都更改为textboxfor,而我的默认值没有显示) “我的编辑”视图接收一个包含两个模型的视图模型,一个空表单(OfferForm)将填充屏幕上的字段,另一个

我已经看过这篇文章:

但我无法更改为
Html.TextAreaFor()
,因为它没有一个属性可供我设置动态默认值(我正在创建一个编辑页面,我希望动态填充当前数据的字段,然后可以修改这些字段)。即使我在viewmodel中更改为
[DataType(DataType.multilitext)]
,我似乎也无法让编辑器for工作(它所做的一切似乎都更改为textboxfor,而我的默认值没有显示)

“我的编辑”视图接收一个包含两个模型的视图模型,一个空表单(
OfferForm
)将填充屏幕上的字段,另一个是包含当前数据的
offer
模型。我想为
报价表单
创建文本字段,并用
报价
模型数据的内容动态填充它们

这是我的html:

<div class="InLine">
                    <div class="InLine editor-label-container">
                        <div class="editor-label">
                            @Html.LabelFor(model => model.OfferForm.Description)
                        </div>
                    </div>
                    <div class="InLine editor-field-container">
                        <div class="editor-field">
                            @Html.TextBoxFor(model => model.OfferForm.Description, new { @Value = @Html.DisplayFor(model => model.Offer.Description)})
                            @Html.ValidationMessageFor(model => model.Offer.Description)
                        </div>
                    </div>
                </div>
                <div class="InLine">
                    <div class="InLine editor-label-container">
                        <div class="editor-label">
                            @Html.LabelFor(model => model.OfferForm.SMSText)
                        </div>
                    </div>
                    <div class="InLine editor-field-container">
                        <div class="editor-field">
                            @Html.TextBoxFor(model => model.OfferForm.SMSText, new { @Value = @Html.DisplayFor(model => model.Offer.SmsText)})
                            @Html.ValidationMessageFor(model => model.Offer.SmsText)
                        </div>
                    </div>
                </div>

@LabelFor(model=>model.OfferForm.Description)
@TextBoxFor(model=>model.OfferForm.Description,新的{@Value=@Html.DisplayFor(model=>model.Offer.Description)})
@Html.ValidationMessageFor(model=>model.Offer.Description)
@LabelFor(model=>model.OfferForm.SMSText)
@Html.TextBoxFor(model=>model.OfferForm.SMSText,新的{@Value=@Html.DisplayFor(model=>model.Offer.SMSText)})
@Html.ValidationMessageFor(model=>model.Offer.SmsText)

有没有办法在
Html.TextBoxFor()
中设置“
multiline
”属性?

您必须意识到Html元素不是windows控件,它们只是在某种程度上映射到它们

HTML元素必须是跨平台的,并且不能保证textarea在所有平台上都只是一个多行文本框,因此就HTML而言,textbox和textarea是两个不同的东西


因此答案是否定的,因为HTML中没有文本框的多行属性。

您必须意识到HTML元素不是windows控件,它们只是在某种程度上映射到它们

HTML元素必须是跨平台的,并且不能保证textarea在所有平台上都只是一个多行文本框,因此就HTML而言,textbox和textarea是两个不同的东西


因此答案是否定的,因为HTML中没有文本框的多行属性。

最简单的方法是创建如下HTML扩展方法

public static class HtmlTextAreaExtensions {

    public static IHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int cols, object htmlAttributes = null, string Value = null) {
        return TextAreaFor<TModel, TProperty>(htmlHelper, expression, rows, cols, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), Value);
    }

    public static IHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int cols, IDictionary<string, string> htmlAttributes = null, string Value = null) {
        var modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var name = ExpressionHelper.GetExpressionText(expression);

        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        Dictionary<string, object> rowsAndColumns = new Dictionary<string, object>();
        if (rows > 0) {
            rowsAndColumns.Add("rows", rows.ToString(CultureInfo.InvariantCulture));
        } else {
            rowsAndColumns.Add("rows", "5");
        }
        if (cols > 0) {
            rowsAndColumns.Add("cols", cols.ToString(CultureInfo.InvariantCulture));
        } else {
            rowsAndColumns.Add("cols", "20");
        }
        TagBuilder tagBuilder = new TagBuilder("textarea");
        tagBuilder.GenerateId(fullName);
        tagBuilder.MergeAttributes(htmlAttributes, true);
    tagBuilder.MergeAttributes(rowsAndColumns, false);  // Only force explicit rows/cols
        tagBuilder.MergeAttribute("name", fullName, true);

        // If there are any errors for a named field, we add the CSS attribute.
        ModelState modelState;
        if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0) {
            tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
        }

        tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));

        string value;
        if (Value != null) {
            value = Value;
        } else if (modelState != null && modelState.Value != null) {
            value = modelState.Value.AttemptedValue;
        } else if (modelMetadata.Model != null) {
            value = modelMetadata.Model.ToString();
        } else {
            value = String.Empty;
        }

        // The first newline is always trimmed when a TextArea is rendered, so we add an extra one
        // in case the value being rendered is something like "\r\nHello".
        tagBuilder.SetInnerText(Environment.NewLine + value);

        return new HtmlString(tagBuilder.ToString(TagRenderMode.Normal));
    }
}
它只支持基本功能,什么都不支持。实际的标记生成是从Mvc3源代码中提取的,只是做了一些轻微的更改,以支持传入值。这应该适用于大多数情况,但您可能需要添加更多覆盖。这不是很…干净,但应该可以让你走了。:)


要使扩展显示在razor视图中,请编辑视图目录中的
Web.config
,并在放置此类的位置添加命名空间(而不是类名)。然后,它将显示在intellisense中。

最简单的方法是创建一个Html扩展方法,如下所示

public static class HtmlTextAreaExtensions {

    public static IHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int cols, object htmlAttributes = null, string Value = null) {
        return TextAreaFor<TModel, TProperty>(htmlHelper, expression, rows, cols, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), Value);
    }

    public static IHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int cols, IDictionary<string, string> htmlAttributes = null, string Value = null) {
        var modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var name = ExpressionHelper.GetExpressionText(expression);

        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        Dictionary<string, object> rowsAndColumns = new Dictionary<string, object>();
        if (rows > 0) {
            rowsAndColumns.Add("rows", rows.ToString(CultureInfo.InvariantCulture));
        } else {
            rowsAndColumns.Add("rows", "5");
        }
        if (cols > 0) {
            rowsAndColumns.Add("cols", cols.ToString(CultureInfo.InvariantCulture));
        } else {
            rowsAndColumns.Add("cols", "20");
        }
        TagBuilder tagBuilder = new TagBuilder("textarea");
        tagBuilder.GenerateId(fullName);
        tagBuilder.MergeAttributes(htmlAttributes, true);
    tagBuilder.MergeAttributes(rowsAndColumns, false);  // Only force explicit rows/cols
        tagBuilder.MergeAttribute("name", fullName, true);

        // If there are any errors for a named field, we add the CSS attribute.
        ModelState modelState;
        if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0) {
            tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
        }

        tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));

        string value;
        if (Value != null) {
            value = Value;
        } else if (modelState != null && modelState.Value != null) {
            value = modelState.Value.AttemptedValue;
        } else if (modelMetadata.Model != null) {
            value = modelMetadata.Model.ToString();
        } else {
            value = String.Empty;
        }

        // The first newline is always trimmed when a TextArea is rendered, so we add an extra one
        // in case the value being rendered is something like "\r\nHello".
        tagBuilder.SetInnerText(Environment.NewLine + value);

        return new HtmlString(tagBuilder.ToString(TagRenderMode.Normal));
    }
}
它只支持基本功能,什么都不支持。实际的标记生成是从Mvc3源代码中提取的,只是做了一些轻微的更改,以支持传入值。这应该适用于大多数情况,但您可能需要添加更多覆盖。这不是很…干净,但应该可以让你走了。:)


要使扩展显示在razor视图中,请编辑视图目录中的
Web.config
,并在放置此类的位置添加命名空间(而不是类名)。然后它应该在intellisense中显示。

所以没有办法使用多行文本框或带有默认值参数的文本区域?如果我将editorfor用作editorfor(Offer),我可以获得一个editorfor来做我想做的事情,但是我想要一个editorfor(OfferForm),但我希望它包含Offer信息,所以我不能这样做。我运气不好吗?@Evan Layman-我不知道默认值,我只是简单地回答你关于多行文本框的问题。谢谢你的回答,我很感激你的回答,我只是希望有一些方法可以让html元素显示为我想要的样子:)所以没有办法让多行文本框或带有默认值参数的文本区域?如果我将editorfor用作editorfor(Offer),我可以获得一个editorfor来做我想做的事情,但是我想要一个editorfor(OfferForm),但我希望它包含Offer信息,所以我不能这样做。我运气不好吗?@Evan Layman-我不知道默认值,我只是简单地回答你关于多行文本框的问题。谢谢你的回答,我很感激你的回答,我只是希望有某种方法可以让html元素按我的意愿显示:)你为什么要设置
属性。对于文本区域,
是html元素中包含的内容。至于您的示例,当您使用
Html.
helper时,您不需要为
TextBoxFor
TextAreaFor
设置value属性,它会自动填充值。@BuildStarted-我需要设置
值的原因是该值不是从我所属的模型填充的使用<代码>文本BOX/<代码>或<代码>文本> <代码>(即空白提供表单)。相反,它是从我的ViewModel(即报价)中的第二个模型填充的。啊,我明白了。非常微妙的命名