问题
Why can't I set ShowForEdit
model metadata with an attribute?
It seems that the only attribute provided to alter this is [ScaffoldColumn]
, which sets both ShowForEdit
and ShowForDisplay
, which is not what I want to do. I want to be able to annotate the two separately from on my model.
回答1:
Because it is not supported out of the box. AFAIK the reason is because the dataannotations attribute that support this functionality are in .net 4.0 and in order to make MVC 3.5 and 4.0 compatible they had to be excluded.
The easiest way to fix this is to have to implement your own Edit/Show attribute as demonstrated in this Question/Answer:
Showing Different fields in EditorForModel vs. DisplayForModel modes in MVC2
回答2:
What is the type of property you are applying it to? If we use Reflector, we can discover that the ShowForEdit and ShowForDisplay properties are used in the following functions:
ShowForEdit: System.Web.Mvc.Html.DefaultEditorTemplates.ShouldShow(...)
ShowForDisplay: System.Web.Mvc.Html.DefaultDisplayTemplates.ShouldShow(...)
The definition of these methods is:
private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo)
{
return (((metadata.ShowForEdit && (metadata.ModelType != typeof(EntityState))) && !metadata.IsComplexType) && !templateInfo.Visited(metadata));
}
private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo)
{
return (((metadata.ShowForDisplay && (metadata.ModelType != typeof(EntityState))) && !metadata.IsComplexType) && !templateInfo.Visited(metadata));
}
Ignoring the obvious property check (metadata.ShowForX), you can see that it is checking whether the model is an instance of EntityState (probably isn't), and then a check for metadata.IsComplexType.
We can look at the IsComplexType property here:
public virtual bool IsComplexType
{
get
{
return !TypeDescriptor.GetConverter(this.ModelType).CanConvertFrom(typeof(string));
}
}
What that is saying is that it will return true if the model cannot be converted from a string, and in the ShouldShow() methods, it will show if it is not a complex type, i.e., the value CAN be converted from a string.
What you will need to do, is create a TypeConverter that can convert a string, to the model, e.g:
A model:
[TypeConverter(typeof(ItemConverter))]
public class Item
{
#region Properties
public string Text { get; set; }
#endregion
}
And a converter:
public class ItemConverter : TypeConverter
{
#region Methods
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value.GetType() == typeof(string))
{
return new Item { Text = (string)value };
}
return base.ConvertFrom(context, culture, value);
}
#endregion
}
With that in place, try it again and see if that helps.
来源:https://stackoverflow.com/questions/3013051/asp-net-mvc-why-cant-i-set-showforedit-model-metadata-with-an-attribute