9

我正在寻找使用属性将视图模型属性标记为只读,以便视图字段在渲染视图中只读。应用 System.ComponentModel.DataAnnotations.EditableAttribute 似乎是我需要的确切属性,但它似乎不起作用,即文本框字段仍然是可编辑的。我环顾四周,找不到答案,只有几个相关的问题。呈现视图时,下面应用的可编辑属性不起作用。

[Display(Name = "Last Name")]
[Editable(false, AllowInitialValue = true)]
public string LastName { get; set; }

我可以使用这样的视图辅助函数来实现只读行为,但我更喜欢在模型属性上使用属性。

@functions {
    object getHtmlAttributes()
    {
    if (@ViewBag.Mode == "Edit")
    {
      return new {style = "width:100px;background:#ff6;", @readonly = "readonly"};
    }

    return new { style = "width:100px;" };  
}
} 

@Html.TextBoxFor(model => model.FirstName, getHtmlAttributes())

其他属性可以正常工作,包括自定义验证属性。你能告诉我数据注释可编辑属性是否在这种情况下工作,应该像上面应用的那样工作,还是需要做其他事情?谢谢。

4

5 回答 5

5

EditableAttribute 文档指出:

数据字段上存在的 EditableAttribute 属性指示用户是否应该能够更改字段的值。

此类既不强制也不保证字段是可编辑的。无论此属性是否存在,底层数据存储都可能允许更改字段。

不幸的是,这意味着使用此属性对 MVC 中的验证没有任何影响。这感觉是错误的,但如果您考虑在 MVC 框架中实现它需要什么,它是有道理的。例如,在典型的“编辑”视图中,用户执行初始 GET 请求,其中填充模型(通常来自数据库记录)并提供给视图以呈现给用户。然后用户进行一些编辑,然后提交表单。提交表单会导致从 POST 参数构造模型的新实例。验证器很难确保两个对象实例中的字段具有相同的值,因为其中一个实例(来自 GET 请求的第一个实例)已经被处理掉了。

好吧,如果属性没有功能,为什么还要费心使用它呢?

我最好的猜测是,他们希望开发人员在他们的代码中使用它来表达意图。更实际的是,您还可以编写自己的自定义代码来检查此属性的存在...

AttributeCollection attributes = TypeDescriptor.GetAttributes(MyProperty);
if (attributes[typeof(EditableAttribute)].AllowEdit)
{
   // editable
}
else
{
   // read-only
}

还要记住,这些 DataAnnotation 属性不仅适用于 MVC 应用程序,它们还可以用于许多不同类型的应用程序。即使 MVC 没有对这个 Attribute 做任何特别的事情,其他框架已经为这个 Attribute 实现了功能/验证

于 2012-11-28T18:05:36.253 回答
2

我自己只是半解决了这个问题。

[隐藏输入(显示值=真)]

该字段显示但不可编辑。

于 2012-07-07T03:00:17.993 回答
1

发现在模型上使用 Editable 而不是 Readonly 的效果完全一样。

[ReadOnly(true)] //or
[Editable(false)]
public string Name { get; set; }

当查询视图本身的属性时,此语法确实有效。当属性为 Editable(true) 时也有效

@if (ViewData.ModelMetadata.Properties.Where(p => p.PropertyName == "Name").First().IsReadOnly)
{ 
    @Html.TextBoxFor(model => model.Name, new { style = "width:190px; background-color: #ffffd6", @readonly =  "readonly" })
} 
else
{
    @Html.TextBoxFor(model => model.Name, new { style = "width:190px; " })
}

在此处使用编辑器模板是一个简单的字符串模板:

@model String
@{
IDictionary<string, object> htmlAttributes = new Dictionary<string, object>();
if (ViewData.ModelMetadata.IsReadOnly) //this will be looking at the actual property not the complete model
{
htmlAttributes.Add("style", "width:100px; background-color:#ffffd6");
htmlAttributes.Add("readonly", "readonly");
@Html.TextBox("", Model, htmlAttributes)
}
于 2012-11-29T20:11:02.487 回答
1

你有不同的创建场景吗?您允许初始值的任何特殊原因?我问是因为文档说:

因为您通常希望两个属性包含相同的值,所以 AllowInitialValue 属性设置为类构造函数中 AllowEdit 的值。

我在想如果你将它设置为 false 并且没有明确声明AllowInitialValue它会起作用。

于 2012-04-13T15:08:13.497 回答
0

不知道你是否已经弄清楚了,但我们使用

System.ComponentModel.ReadOnlyAttribute

用法

[ReadOnly(true)]
于 2012-11-06T21:49:07.630 回答