Skip to content

Instantly share code, notes, and snippets.

@neoGeneva
Created May 18, 2012 02:23
Show Gist options
  • Save neoGeneva/2722775 to your computer and use it in GitHub Desktop.
Save neoGeneva/2722775 to your computer and use it in GitHub Desktop.
ASP.NET MVC3 EditorFor that looks for inheritance
public static MvcHtmlString EditorForInherited<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
if (htmlHelper.ViewContext.ViewData.Model == null)
return htmlHelper.EditorFor(expression);
var modelType = htmlHelper.ViewContext.ViewData.Model.GetType();
if (modelType == typeof(TModel))
return htmlHelper.EditorFor(expression);
var propertyType = typeof(TProperty);
var funcType = typeof(Func<,>)
.MakeGenericType(modelType, propertyType);
var parameterExpression = Expression.Parameter(modelType);
var propertyExpression = Expression.Property(parameterExpression, ((MemberExpression)expression.Body).Member.Name);
var newExpression = typeof(Expression)
.GetMethods()
.First(x => x.Name == "Lambda" && x.ContainsGenericParameters && x.GetParameters().Length == 2)
.MakeGenericMethod(funcType)
.Invoke(null, new object[] { propertyExpression, new ParameterExpression[] { parameterExpression } });
var newHtmlHelper = (HtmlHelper)typeof(HtmlHelper<>)
.MakeGenericType(modelType)
.GetConstructor(new[] { typeof(ViewContext), typeof(IViewDataContainer), typeof(RouteCollection) })
.Invoke(new object[] { htmlHelper.ViewContext, htmlHelper.ViewDataContainer, htmlHelper.RouteCollection });
return (MvcHtmlString)
typeof(EditorExtensions)
.GetMethods()
.Single(x => x.Name == "EditorFor" && x.GetParameters().Count() == 2)
.MakeGenericMethod(modelType, propertyType)
.Invoke(null, new object[] { newHtmlHelper, newExpression });
}
@neoGeneva
Copy link
Author

public class BaseClass 
{
    public virtual string SomeProperty { get; set; }
}

public class InheritedClass : BaseClass
{
    [Required()]
    public override string SomeProperty { get; set; }
}

@neoGeneva
Copy link
Author

<%@ Control Language="C#" Inherits="ViewUserControl<BaseClass>" %>

<%:Html.EditorFor(m => m.SomeProperty)%>
<%:Html.EditorForInherited(m => m.SomeProperty)%>

@neoGeneva
Copy link
Author

<input data-val="true" id="SomeProperty" name="SomeProperty" type="text">
<input data-val="true" data-val-required="The SomeProperty field is required." id="SomeProperty" name="SomeProperty" type="text">

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment