开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜