Reputation: 1601
I have a model (simplified for relevance) like this:
public abstract class TitleCreateModel : ICreateModel
{
[Required]
[MaxLength(400)]
public string TitleName { get; set; }
[Required]
[MaxLength(4)]
public DateTime ReleaseDate { get; set; }
[Required]
[MaxLength(5)]
public string Test { get; set; }
[Required]
[MaxLength(2)]
public int Wut { get; set; }
}
Then I have a custom HTML helper class and an Expression extension class (both unabridged):
public class InputHelper
{
public static HtmlString Input<T>(Expression<Func<T, Object>> expression, string id, string label)
{
var req = expression.GetAttribute<T, Object, RequiredAttribute>();
var max = expression.GetAttribute<T, Object, MaxLengthAttribute>();
var required = "";
var maxlength = "";
if(req!=null)
{
required = "req";
}
if(max!=null)
{
maxlength = "maxlength='" + max.Length + "'";
}
return new HtmlString("<div class=\"clearfix\"><label for=\""+id+"\">" + label + "</label>" +
"<div class=\"input\"><input id=\""+id+"\" class=\""+required+"\" type=\"text\" "+maxlength+"/></div></div>");
}
}
public static class ExpressionExtensions
{
public static TAttribute GetAttribute<TIn, TOut, TAttribute>(this Expression<Func<TIn, TOut>> expression) where TAttribute : Attribute
{
var memberExpression = expression.Body as MemberExpression;
if (memberExpression != null)
{
var attributes = memberExpression.Member.GetCustomAttributes(typeof(TAttribute), true);
return attributes.Length > 0 ? attributes[0] as TAttribute : null;
}
return null;
}
}
In my Razor script, I make the following calls:
@(InputHelper.Input<string>(m => Model.Title.TitleName, "titlename", "Title Name"))
@(InputHelper.Input<string>(m => Model.Title.Test, "testfield", "Test Field"))
@(InputHelper.Input<int>(m => Model.Title.Wut, "tester", "Test Field 2"))
@(InputHelper.Input<DateTime>(m => Model.Title.ReleaseDate, "release_year", "Release Year"))
For some reason, the GetAttribute method only finds the attributes for TitleName and Test, both of which are string properties for TitleCreateModel. It's unable to find the attributes for ReleaseDate and Wut, and I have no idea why.
Upvotes: 0
Views: 399
Reputation: 2192
With the DateTime and int, the Expression is not of type MemberExpression, due to the boxing I believe, so this line:
var memberExpression = expression.Body as MemberExpression;
will return a null.
There's a good question and answer on this topic here, which just involves modifying your Func
generic as Eranga as specified.
Upvotes: 1
Reputation: 32437
Modify the expression used in Input
method to Expression<Func<T, TOut>> expression
public static HtmlString Input<T, TOut>(Expression<Func<T, TOut>> expression, string id, string label)
{
var req = expression.GetAttribute<T, TOut, RequiredAttribute>();
var max = expression.GetAttribute<T, TOut, MaxLengthAttribute>();
var required = "";
var maxlength = "";
if(req!=null)
{
required = "req";
}
if(max!=null)
{
maxlength = "maxlength='" + max.Length + "'";
}
return new HtmlString("<div class=\"clearfix\"><label for=\""+id+"\">" + label + "</label>" +
"<div class=\"input\"><input id=\""+id+"\" class=\""+required+"\" type=\"text\" "+maxlength+"/></div></div>");
}
Upvotes: 1