Readonly根据条件标记MVC

时间:2013-11-26 13:49:58

标签: c# asp.net-mvc asp.net-mvc-4

我的模型有一个属性,我指定了一个ReadOnly标记。我的目的是根据像

这样的条件设置一个真正或错误的属性
class Test {
  static bool test() { // It is my model
    // My logical response ...
    return true;
  }


  [ReadOnly(test)]
  datetime prop {get; set;}

}

使用此模型我收到错误消息:

Error   7 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter

请问,请问我这个想法?

=============================================== ======================================

解决方案如答案3:

内部模板:

CSHTML:

    ...
    @if (Model.condition) {
    <td>@Html.EditorFor(m => m.prop)</td>
    } else {
    <td>@Html.DisplayFor(m => m.prop)</td>
    }
    ...

它将在模板内。

copmnstructor中的Inside Model我设置了属性条件的条件:

class XX {
  public condition { get; set; } // not necessary readonly, I do the logical inside the template.
  public datetime prop {get; set; }

  public XX (bool _condition) {
     condition = _condition;
  }
}

3 个答案:

答案 0 :(得分:0)

您不能使用错误消息中描述的其他内容作为属性参数。

这是一个悲伤的事实,但仍然是真的。

只有这个:

[ReadOnly(5)]
[ReadOnly("string")] // Or other type (int/long/byte/etc..) which can be used with const keyword.
[ReadOnly(Enums.SomeValue)]
[ReadOnly(typeof(SomeType))]
[ReadOnly(new string[] { "array", "of", "strings"} )]

所以不幸的是,你不会成功制作自定义参数类型:

class ReadOnlyAttribute { ReadOnlyAttribute(MyClass foo) { ... } }

答案 1 :(得分:0)

另一种选择是在get / set中执行此操作,例如:

class test
{
  static bool test() {
    ...
  }

  private datetime prop;

  public datetime Prop
  {
    get { return prop; }
    set
    {
      if (test)
        prop = value;
      else
        // Ignore, throw exception, etc.
    }
  }
}

答案 2 :(得分:0)

The metadata for the model (which includes your IsReadOnly)由模型元数据提供程序创建。此提供程序仅包含有关数据类型和属性名称的信息,但不包含有关模型实例属性的具体值的信息。因此,元数据不能依赖于模型类的属性或方法的值。 (因此实现Custom ModelMetada Provider无法解决您的问题。)

然后,你必须找到一种替代的,黑客的方式来做到这一点:

  • 创建一个视图模型,其中包含两个属性,原始的,没有readonly属性和另外的readonly属性,使用readonly属性修饰。
  • 在视图中,决定显示两者中的哪一个。

    public class MyModel
    {
        public DateTime MyProperty { get; set;}
    
        [ReadOnly]
        public DateTime MyPropertyRo { get; set;}
    }
    

如果要恢复发布的值,可编辑版本应使用Telerik控件中的原始属性。不可编辑的版本应该使用Telerik控件中的readonly属性,以及隐藏字段中的原始属性,以便您可以在帖子中恢复它。

  @if (Model.MyPropertyIsReadOnly)
  {
     @Html.HiddenFor(m => m.Property)
     @Html.TelerikEditorFor(m => m.PropertyRo ...)
  }
  else
  {
     @Html.TelerikEditorFor(m => m.Property ...)
  }

如果必须在许多不同的视图中执行此操作,您可以创建一个Html帮助程序(Html的扩展方法),它接收3个属性并包含最后一个示例代码。

最后,制作一个custom Editor template会更好,但如果你没有经验,那就更难了。

还有另一种选择:联系telerik,并要求他们实现一个接收readonly参数的控件版本,并自动为您执行此操作。我认为实施它一定很容易。所以,如果你足够幸运......