【问题标题】:MVC 4 razor Data Annotations ReadOnlyMVC 4 razor 数据注释只读
【发布时间】:2013-08-29 15:45:00
【问题描述】:

ReadOnly 属性似乎不在 MVC 4 中。Editable(false) 属性无法按我希望的方式工作。

有没有类似的方法有效?

如果不是,那么我怎样才能让我自己的 ReadOnly 属性像这样工作:

public class aModel
{
   [ReadOnly(true)] or just [ReadOnly]
   string aProperty {get; set;}
}

所以我可以这样说:

@Html.TextBoxFor(x=> x.aProperty)

而不是这个(确实有效):

@Html.TextBoxFor(x=> x.aProperty , new { @readonly="readonly"})

或者这个(确实有效但没有提交值):

@Html.TextBoxFor(x=> x.aProperty , new { disabled="disabled"})

http://view.jquerymobile.com/1.3.2/dist/demos/widgets/forms/form-disabled.html

可能是这样的吗? https://stackoverflow.com/a/11702643/1339704

注意:

[Editable(false)] 无效

【问题讨论】:

    标签: c# jquery-mobile asp.net-mvc-4 razor data-annotations


    【解决方案1】:

    您可以像这样创建一个自定义帮助器来检查属性是否存在ReadOnly 属性:

    public static MvcHtmlString MyTextBoxFor<TModel, TValue>(
        this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
        // in .NET 4.5 you can use the new GetCustomAttribute<T>() method to check
        // for a single instance of the attribute, so this could be slightly
        // simplified to:
        // var attr = metaData.ContainerType.GetProperty(metaData.PropertyName)
        //                    .GetCustomAttribute<ReadOnly>();
        // if (attr != null)
        bool isReadOnly = metaData.ContainerType.GetProperty(metaData.PropertyName)
                                  .GetCustomAttributes(typeof(ReadOnly), false)
                                  .Any();
    
        if (isReadOnly)
            return helper.TextBoxFor(expression, new { @readonly = "readonly" });
        else
            return helper.TextBoxFor(expression);
    }
    

    属性很简单:

    public class ReadOnly : Attribute
    {
    
    }
    

    对于示例模型:

    public class TestModel
    {
        [ReadOnly]
        public string PropX { get; set; }
        public string PropY { get; set; }
    }
    

    我已经验证了这适用于以下剃须刀代码:

    @Html.MyTextBoxFor(m => m.PropX)
    @Html.MyTextBoxFor(m => m.PropY)
    

    呈现为:

    <input id="PropX" name="PropX" readonly="readonly" type="text" value="Propx" />
    <input id="PropY" name="PropY" type="text" value="PropY" />
    

    如果您需要disabled 而不是readonly,您可以轻松地相应地更改助手。

    【讨论】:

    • 有没有办法让它与任何 Html 助手一起工作,而不是创建一个新的 Html 助手?
    • 没有办法让它以你想要的方式与所有助手一起工作。这就是为什么大多数助手都有可选的htmlAttributes 参数,可以让你根据需要指定readonly 之类的东西。我的上述解决方案是您必须如何根据您给出的要求来实现它,即使用属性。另一个解决方案,虽然我认为它不会比指定 @readonly = "readonly" 更干净,但它是创建一个扩展来处理从帮助程序输出的 HTML,即 @Html.TextBoxFor().Readonly()
    • 好的,我决定只使用 htmlAttributes,因为它更简单......但我会接受你的回答,因为它似乎是我的问题最接近的答案。
    【解决方案2】:

    您可以创建自己的 Html Helper 方法

    请看这里: Creating Customer Html Helpers

    其实-看看this answer

     public static MvcHtmlString MyTextBoxFor<TModel, TProperty>(
             this HtmlHelper<TModel> helper, 
             Expression<Func<TModel, TProperty>> expression)
        {
            return helper.TextBoxFor(expression, new {  @readonly="readonly" }) 
        }
    

    【讨论】:

    • 这看起来很有希望......我可以创建一个名为 ReadOnlyTextBoxFor 或类似的东西......我想数据注释是多余的。
    • 没错,在我看来,这样做是在正确的地方。我不认为数据注释是您定义本质上是表示属性的方式
    • 数据注解可以而且经常确实提供用于显示属性的信息,即DisplayDisplayFormat 数据注解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多