asp.net-mvc-3 - 如何在 .NET MVC 中读取属性数据注释值

标签 asp.net-mvc-3

我刚开始使用 ASP.NET MVC 3,我正在尝试为创建/编辑 View 上的 ViewModel 上的字符串属性呈现以下 HTML。

<input id="PatientID" name="PatientID" placeholder="Patient ID" type="text" value="" maxlength="30" />

每个值都与 ViewModel 上的属性相关联,id 和 name 是属性名称,placeholder 是 Display 属性,value 是属性的值,maxlength 是 StringLength 属性。

我想我会尝试使用 SingleLineTextBox 的名称创建一个 EditorTemplate 并在我的字符串属性上使用 UIHint 或在我调用 EditFor 时传递 View 的名称,而不是输入上面的 HTML 和我的每个字符串属性的正确值.到目前为止一切顺利,除了我不知道如何从 StringLength 属性中获取 maxlength 值。

这是我到目前为止的代码:
<input id="@ViewData.ModelMetadata.PropertyName" name="@ViewData.ModelMetadata.PropertyName" placeholder="@ViewData.ModelMetadata.DisplayName" type="text" value="@ViewData.Model" maxlength="??" />

如您所见,不确定如何设置 maxlength 值。有谁知道怎么做?

另外,我是不是最好的方法?正如我之前所说,我可以自己为页面上的每个属性写出纯 HTML。我看过使用 TextBoxFor 它没有设置 maxlength 并且由于我不想要的 StringLength 属性而向 HTML 输出添加了一堆验证标记。我看到的另一个选项是 HTML 类的扩展/帮助程序。

最佳答案

tvanfosson 答案的完整代码示例:

模型:

public class Product
{
    public int Id { get; set; }

    [MaxLength(200)]
    public string Name { get; set; }

EditorTemplates\String.cshtml
@model System.String
@{
    var metadata = ViewData.ModelMetadata;
    var prop = metadata.ContainerType.GetProperty(metadata.PropertyName);
    var attrs = prop.GetCustomAttributes(false);

    var maxLength = attrs.OfType<System.ComponentModel.DataAnnotations.MaxLengthAttribute>().FirstOrDefault();
}
<input id=@Html.IdForModel()@(metadata.IsRequired ? " required" : "")@(maxLength == null ? "" : " maxlength=" + maxLength.Length) />

HTML 输出:
<input id=Name maxlength=200 />

丑陋但有效。现在让我们对其进行抽象并清理一下。助手类:
public static class EditorTemplateHelper
{
    public static PropertyInfo GetPropertyInfo(ViewDataDictionary viewData)
    {
        var metadata = viewData.ModelMetadata;
        var prop = metadata.ContainerType.GetProperty(metadata.PropertyName);
        return prop;
    }

    public static object[] GetAttributes(ViewDataDictionary viewData)
    {
        var prop = GetPropertyInfo(viewData);
        var attrs = prop.GetCustomAttributes(false);
        return attrs;
    }

    public static string GenerateAttributeHtml(ViewDataDictionary viewData, IEnumerable<Delegate> attributeTemplates)
    {
        var attributeMap = attributeTemplates.ToDictionary(t => t.Method.GetParameters()[0].ParameterType, t => t);
        var attrs = GetAttributes(viewData);

        var htmlAttrs = attrs.Where(a => attributeMap.ContainsKey(a.GetType()))
            .Select(a => attributeMap[a.GetType()].DynamicInvoke(a));

        string s = String.Join(" ", htmlAttrs);
        return s;
    }
}

编辑器模板:
@model System.String
@using System.ComponentModel.DataAnnotations;
@using Brass9.Web.Mvc.EditorTemplateHelpers;
@{
    var metadata = ViewData.ModelMetadata;

    var attrs = EditorTemplateHelper.GenerateAttributes(ViewData, new Delegate[] {
        new Func<StringLengthAttribute, string>(len => "maxlength=" + len.MaximumLength),
        new Func<MaxLengthAttribute, string>(max => "maxlength=" + max.Length)
    });

    if (metadata.IsRequired)
    {
        attrs.Add("required");
    }

    string attrsHtml = String.Join(" ", attrs);
}
<input type=text id=@Html.IdForModel() @attrsHtml />

因此,您传入一个委托(delegate)数组,并为每个条目使用 Func<AttributeTypeGoesHere, string> ,然后为每个属性返回您想要的任何 HTML 字符串。

这实际上很好地解耦了——你可以只映射你关心的属性,你可以为同一个 HTML 的不同部分映射不同的集合,最终的用法(如 @attrsHtml )不会损害模板的可读性。

关于asp.net-mvc-3 - 如何在 .NET MVC 中读取属性数据注释值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8112179/

相关文章:

asp.net-mvc-3 - VS2010 组件的正确安装顺序是什么? (IIS Express、SQL CE、MVC3、SP1 测试版)

asp.net - 使用 MVC4 自定义错误处理

.net - 为什么 Razor 声明性 @helper 方法中的 HtmlHelper 实例为 null?

asp.net-mvc-3 - 模拟 Request.QueryString 用于单元测试并针对 View 进行断言

asp.net-mvc-3 - SSL 证书将加密我的 MVC 3 应用程序中使用的查询字符串值

c# - 在 LINQ 中查询子集合 2 层深

asp.net-mvc-3 - ASP.NET MVC3 中 <text> 的 "Return type"

asp.net-mvc - MVC Controller 中的单一职责原则。需要批评

jquery - ASP MVC3 Ajax Razor View ,如何启用浏览器历史记录?

asp.net-mvc-3 - 如何将 nhibernate 事务添加到 ninject?