在 ASP.NET MVC 中,如何以 CamelCase 形式将属性名称显示为标签拆分

问题描述 投票:0回答:5

我知道我以前见过这个。 我不记得它是 C4MVC 模板演示还是输入生成器! 我需要知道如何使用 CamelCasing 视图模型属性的约定,并将“CamelCasedProperty”在标签中呈现为“Camel Cased Property”。 这应该由创建新视图向导来处理,而不是以编程方式处理。

asp.net-mvc-2
5个回答
21
投票

我认为你想要的东西在普通的 ASP.NET MVC 2 中是不可能的。

在 ASP.NET MVC 2 中,您需要使用 DisplayName 属性和所需的文本来装饰模型,然后自动生成的向导将使用

LabelFor
输出属性的标签。例如:

class MyModel()
{
    [DisplayName("Your Property Name")]
    public string YourPropertyName { get; set; }
}

然后在视图中:

<%= Html.LabelFor(m => m.YourPropertyName) %>

如果您看到以其他方式完成的演示,它可能来自 InputBuilders 的 MvcContrib 项目。

这是我认为您所指的项目部分的直接链接:

http://www.lostechies.com/blogs/hex/archive/2009/06/09/opinionated-input-builders-for-asp-net-mvc-part-2-html-layout-for-the-标签.aspx

以红色突出显示的文本是来自模型类型的标签。标签是从代表模式各自属性的 PropertyInfo 对象创建的。

标签是属性名称。

标签是按 pascal 大小写属性名称拆分的属性名称。

标签是通过使用应用于属性的标签属性来指定的。


7
投票

经过一番探索后,我找到了我感兴趣的事情的线索。 观看这个C4MVC 视频。 我确信这可能已经在 MVC Contrib 中作为输入构建器完成。 然而,我非常有兴趣了解所有的底层内容,可以说,我可以为我即将出版的书“ASP.NET MVC Cookbook”(供公众审查的无耻插件)学习所有内容。 这是我想出的解决方案,只需要我在生成的代码形式“创建新视图”中将 Html.LabelFor 重命名为 Html.LabelFor2:

我创建了一个方法来从传入的 lambda 中获取属性名称。 然后,我创建了另一种方法来解析名称中包含的大写字母的属性名称。

using System;
using System.Linq.Expressions;
using System.Text.RegularExpressions;

namespace FuryPartners.WebClient.Helpers
{
    public class HelperUtilities
    {
        internal static string PropertyName<T, TResult>(Expression<Func<T, TResult>> expression)
        {
            switch (expression.Body.NodeType)
            {
                case ExpressionType.MemberAccess:
                    var memberExpression = expression.Body as MemberExpression;
                    return memberExpression.Member.Name;
                default:
                    return "oops";
            }
        }

        internal static string SplitCamelCase(string camelCaseString)
        {
            string output = System.Text.RegularExpressions.Regex.Replace(
                camelCaseString,
                "([A-Z])",
                " $1",
                RegexOptions.Compiled).Trim();
            return output;
        }
    }
}

然后,我扩展了 HtmlHelper 以拥有一个 LabelFor2 方法,该方法构建并传递属性名称的适当显示格式。

using System;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace FuryPartners.WebClient.Helpers
{
    public static class LabelHelpers
    {
        public static MvcHtmlString LabelFor2<T, TResult>(this HtmlHelper<T> helper, Expression<Func<T, TResult>> expression)
        {
            string propertyName = HelperUtilities.PropertyName(expression);
            string labelValue = HelperUtilities.SplitCamelCase(propertyName);

            string label = String.Format("<label for=\"{0}\">{1}</label>", propertyName, labelValue);
            return MvcHtmlString.Create(label);
        }
    }
}

2
投票

我有一个更简单的新版本,可以从安德鲁斯答案创建标题化标签,使用 MVC2 代码来尊重任何 [DisplayName(...)] 属性

public static class LabelHelpers
{
    public static MvcHtmlString LabelTitleizeFor<T, TResult>(this HtmlHelper<T> helper, Expression<Func<T, TResult>> expression)
    {
        string propertyName = ExpressionHelper.GetExpressionText(expression);

        if (propertyName.IndexOf(".") > 0)
        {
            propertyName = propertyName.Substring(propertyName.LastIndexOf(".") + 1);
        }

        string labelValue = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).DisplayName;

        if (string.IsNullOrEmpty(labelValue))
        {
            labelValue = Inflector.Net.Inflector.Titleize(propertyName);
        }

        string label = String.Format("<label for=\"{0}\">{1}</label>", propertyName, labelValue);
        return MvcHtmlString.Create(label);
    }
}

使用https://github.com/srkirkland/Inflector/blob/master/Inflector/Inflector.cs


0
投票

扩展 Jason More 的答案,这里有一个 HTML 属性重载的答案。

需要 MIT 许可的

Inflector
NuGet 软件包:
Install-Package Inflector

使用示例:

Html.LabelTitleizeFor(model => model.FirstName)
Html.LabelTitleizeFor(model => model.FirstName, htmlAttributes: new { @class="control-label col-md-2" })
public static class HtmlHelperExtensions
{
    public static MvcHtmlString LabelTitleizeFor<T, TResult>(this HtmlHelper<T> helper, Expression<Func<T, TResult>> expression)
    {
        return LabelTitleizeHelper(helper, expression, null);
    }

    public static MvcHtmlString LabelTitleizeFor<T, TResult>(this HtmlHelper<T> helper, Expression<Func<T, TResult>> expression, IDictionary<string, object> htmlAttributes)
    {
        return LabelTitleizeHelper(helper, expression, htmlAttributes);
    }

    public static MvcHtmlString LabelTitleizeFor<T, TResult>(this HtmlHelper<T> helper, Expression<Func<T, TResult>> expression, object htmlAttributes)
    {
        return LabelTitleizeHelper(helper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    private static MvcHtmlString LabelTitleizeHelper<T, TResult>(HtmlHelper<T> html, Expression<Func<T, TResult>> expression, IDictionary<string, object> htmlAttributes = null)
    {
        string propertyName = ExpressionHelper
            .GetExpressionText(expression)
            .Split('.')
            .Last();

        if (string.IsNullOrEmpty(propertyName))
            return MvcHtmlString.Empty;

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

        string labelValue = metadata.DisplayName ?? Inflector.Inflector.Titleize(propertyName);

        TagBuilder tagBuilder = new TagBuilder("label");
        tagBuilder.Attributes.Add("for", TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName)));
        tagBuilder.SetInnerText(labelValue);
        tagBuilder.MergeAttributes(htmlAttributes, true);

        return new MvcHtmlString(tagBuilder.ToString(TagRenderMode.Normal));
    }
}

此代码已获得Unlicense许可(可以在任何情况下免费使用和更改,无需归属)。


0
投票

@DisplayNameFor(m => m.PropertyName) 从视图模型中的显示名称属性获取文本。

© www.soinside.com 2019 - 2024. All rights reserved.