我希望使用属性将视图模型属性标记为只读,以便视图字段仅在渲染视图中读取。应用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())
其他属性完全正常,包括自定义验证属性。你能告诉我数据注释可编辑属性是否在这个上下文中起作用,应该像上面那样工作还是需要做其他事情?感谢。
答案 0 :(得分:4)
EditableAttribute documentation州:
数据字段上存在EditableAttribute属性表示用户是否应该能够更改字段的值。
此类既不强制也不保证字段可编辑。基础数据存储可能允许更改字段,无论是否存在此属性。
不幸的是,这意味着使用此属性对MVC中的验证没有任何影响。这感觉不对,但是如果你想一想在MVC框架中实现它需要什么,这是有道理的。例如,在典型的“编辑”视图中,用户执行初始GET请求,其中填充模型(通常来自DB记录)并将其提供给要呈现给用户的视图。然后用户进行一些编辑,然后提交表单。提交表单会导致从POST参数构造Model的 new 实例。验证器很难确保该字段在两个对象实例中具有相同的值,因为其中一个实例(来自GET请求的第一个实例)已经被处理掉了。
如果属性没有功能,为什么还要费心去使用呢?
我最好的猜测是,他们希望开发人员在代码中使用它来显示意图。更实际的是,您还可以编写自己的自定义代码来检查是否存在此属性...
AttributeCollection attributes = TypeDescriptor.GetAttributes(MyProperty);
if (attributes[typeof(EditableAttribute)].AllowEdit)
{
// editable
}
else
{
// read-only
}
另请注意,这些DataAnnotation属性不仅适用于MVC应用程序,还可用于许多不同类型的应用程序。即使MVC对此属性没有做任何特殊处理,other frameworks have implemented functionality/validation for this attribute。
答案 1 :(得分:2)
我自己刚刚解决了这个问题。
[HiddenInput(DisplayValue = true)]
显示该字段但不可编辑。
答案 2 :(得分:1)
您有不同的创建方案吗?您允许初始值的任何特殊原因?我问,因为documentation说:
因为您通常希望两个属性包含相同的值, AllowInitialValue属性设置为的AllowEdit值 类构造函数。
我在想如果你将它设置为false并且没有明确声明AllowInitialValue
它会起作用。
答案 3 :(得分: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)
}
答案 4 :(得分:0)
不知道你是否已经解决了这个问题,但我们使用了
System.ComponentModel.ReadOnlyAttribute
用法
[ReadOnly(true)]