ModelMetadata: ShowForEdit property not appearing to work
Iv wrote an MetaDataProvider like the one below and am using it in conjunction with Editor templates. The DisplayName is开发者_如何学C working correctly, but for some reason the ShowForEdit value it not having any effect. Any ideas?
public class MyModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType,
Func<object> modelAccessor, Type modelType, string propertyName)
{
var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); I
metadata.DisplayName = "test";
metadata.ShowForEdit = false;
metadata.ShowForDisplay = false;
metadata.HideSurroundingHtml = true;
return metadata;
}
}
This seems similar to the question Why can't I set ShowForEdit model metadata with an attribute?, so I'll replicate my answer here:
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 those 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 intstance 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.
精彩评论