views:

18

answers:

1

I have written a custom DataAnnotationsModelMetadataProvider that sets HideSurroundingHtml dynamically.

public class ContentDrivenModelMetadataProvider : DataAnnotationsModelMetadataProvider
{

        protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType,
                                                        Func<object> modelAccessor, Type modelType, string propertyName)
        {
            ModelMetadata metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType,
                                                         propertyName);

             metadata.HideSurroundingHtml = true;
        }

}

But this doesn't seemed to be picked up by the editor templates. So Iv created a new HTML extension method for the label that tries to force HideSurroundingHtml to work.

public static class HtmlCustom
    {
        public static MvcHtmlString CustomLabelFor<TModel, TProperty>(
                this HtmlHelper<TModel> htmlHelper,
                Expression<Func<TModel, TProperty>> expression)
        {
            if(htmlHelper.ViewData.ModelMetadata.HideSurroundingHtml)
            {
                return MvcHtmlString.Empty;
            }

            return htmlHelper.LabelFor(expression);
        }
    }

But this does no work, furthermore when I attached break points to these, it seems to hit the extension method before the CreateMetadata method - which explains why this is not working, but the fact this it is called in this order does not make sense.

Can any one explain this? or how to achieve what im trying to achieve?

+1  A: 

Here is how to do it:

public static MvcHtmlString CustomLabelFor<TModel, TProperty>(
                 this HtmlHelper<TModel> htmlHelper,
                 Expression<Func<TModel, TProperty>> expression)
        {
            var propertyName = ExpressionHelper.GetExpressionText(expression);
            var htmlString = htmlHelper.LabelFor(expression);

            ModelMetadata modelMetaData = htmlHelper.ViewData.ModelMetadata.Properties.Where(x => x.PropertyName == propertyName).First();

            if (modelMetaData.HideSurroundingHtml)
            {
                htmlString = MvcHtmlString.Empty;
            }
            return htmlString;
        }

There where a couple of issues, had to move htmlHelper.LabelFor to the start of the method as it is this that causes CreateMetadata to fire. Also some extra logic was required to called pull out the right meta data.

Dan