gpt4 book ai didi

asp.net-mvc - 使用 TextBoxFor 设置具有命名空间前缀的 HTML 属性

转载 作者:行者123 更新时间:2023-12-01 22:37:42 25 4
gpt4 key购买 nike

我正在转换一些现有的 HTML 以与 ASP.NET MVC 一起使用,并且有一些包含输入字段的表单,这些字段具有包含命名空间前缀的附加属性(目前,我需要保留这些属性):

<input type="text" foo:required="true" foo:message="Please enter a username" />

我想使用 TextBoxFor帮助器方法重载,允许使用 collection initializer 指定 htmlAttributes语法:

@Html.TextBoxFor(
model => model.Username,
new { foo:required="true", foo:message="Please enter a username" })

但是,由于 foo:required 中的冒号(等),此语法无效。

相反,我必须使用这个更详细的字典初始化语法:

@Html.TextBoxFor(
model => model.Username,
new Dictionary<string, object>
{
{ "foo:required", "true" },
{ "foo:message", "Please enter a username" }
})

是否可以使用第一种语法的变体,以某种方式转义(因为需要更好的词)冒号?

或者

在这种情况下,TextBoxFor 辅助方法并没有真正的帮助,仅保留现有的原始 HTML 并添加 value="@Model.UserName"会更简单吗? input 元素?

最佳答案

第一个语法是使用匿名对象,对于该对象,关于如何 create identifiers in C# 的规则相同。适用:

  • 您可以使用 Lu、Ll、Lt、Lm、Lo 或 Nl 类的任何 unicode 字符
  • 您可以使用“@”对 C# 关键字进行转义,如 new { @class = "foo"};

由于冒号属于Po unicode class它不能用在标识符中。 (在 C# 中,您可以使用静态方法 char.GetUnicodeCategory 来检查任何字符的类别)

此外,仅在 MVC 中,当在帮助程序中使用匿名对象作为 html 属性时,任何带有下划线的属性名称都将被连字符替换。这是由于方法 HtmlHelper.AnonymousObjectToHtmlAttributes

回到您的案例并考虑您的选项,如果这些选项使用得不太广泛(例如在几个 View 中),我会考虑保留 TextBoxFor 帮助器的字典语法。您仍然可以自动生成与模型绑定(bind)同步的 id\name 属性,并且可以从模型元数据中获取任何其他属性,例如不显眼的验证属性。 (尽管查看您想要保留的属性,但似乎您不需要不引人注目的验证属性:))

但是,如果 id\name 就像属性名称一样简单,并且您不需要使用帮助程序自动生成的任何其他 html 属性,那么使用原始 HTML 是有意义的。 (因为字典语法相当难看)

如果您在应用程序中广泛使用它,那么我认为最明智的方法可能是创建您自己的帮助器,例如@Html.LegacyTextBoxFor(...)。该帮助器将呈现您想要保留的那些旧属性,并且您可以合并类似于用于 id\name 属性创建的标准帮助器的附加逻辑。

类似这样的事情:

public class FooAttributes
{
public bool Required { get; set; }
public string Message { get; set; }
}

public static class FooHelper
{
public static MvcHtmlString LegacyTextboxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, FooAttributes fooAttributes)
{
var fieldName = ExpressionHelper.GetExpressionText(expression);
var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);

var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var value = metadata.Model;

TagBuilder tag = new TagBuilder("input");
tag.Attributes.Add("name", fullBindingName);
tag.Attributes.Add("id", fieldId);
tag.Attributes.Add("type", "text");
tag.Attributes.Add("value", value == null ? "" : value.ToString());

if (fooAttributes != null)
{
if (fooAttributes.Required) tag.Attributes.Add("foo:required", "true");
if (!String.IsNullOrEmpty(fooAttributes.Message)) tag.Attributes.Add("foo:message", fooAttributes.Message);
}

return new MvcHtmlString(tag.ToString(TagRenderMode.SelfClosing));
}
}

可以用作:

@Html.LegacyTextboxFor(model => model.UserName, new FooAttributes {Required=true, Message="Please enter a value." })

并且会生成这个html:

<input foo:message="Please enter a value." foo:required="true" id="UserName" name="UserName" type="text" value="">

一旦您有了自己的助手,您就可以添加额外的逻辑,例如将从模型元数据及其数据注释属性生成这些属性的逻辑...

我的回答超出了预期,但我希望它能有所帮助!

关于asp.net-mvc - 使用 TextBoxFor 设置具有命名空间前缀的 HTML 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18192814/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com