-
-
Save LSTANCZYK/22fb5ecf89987df4f7dd3520a19271cb to your computer and use it in GitHub Desktop.
String property allowed values with dropdown box and MVC model validation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Usage: | |
// [AttributeUsage("Option1", "Option2", "Option3")] | |
// public string MyTestAttribute { get; set; } | |
// | |
// In view: | |
// @Html.DropDownListFor(x => x.MyTestAttribute) | |
// | |
// Result: | |
// Dropdown list with 3 options. | |
namespace Extensions | |
{ | |
using System; | |
using System.ComponentModel.DataAnnotations; | |
using System.Linq; | |
/// <summary> | |
/// AllowedValues attribute for string types | |
/// </summary> | |
[AttributeUsage(AttributeTargets.Property, Inherited = false)] | |
public sealed class AllowedValuesAttribute : ValidationAttribute | |
{ | |
public AllowedValuesAttribute(params string[] args) | |
{ | |
Values = args; | |
} | |
public string[] Values { get; set; } | |
public override bool IsValid(object value) | |
{ | |
if (Values.Contains(value)) | |
return true; | |
return false; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// DropDownListFor model property which has AllowedValuesAttribute | |
/// </summary> | |
/// <typeparam name="TModel">Model to create a dropdown for</typeparam> | |
/// <param name="helper">HTML Helper</param> | |
/// <param name="expression">Expression to use</param> | |
/// <param name="htmlAttributes">Attributes to use</param> | |
/// <returns>MVC Html String of Dropdownlist</returns> | |
public static MvcHtmlString DropDownListFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, object>> expression, object htmlAttributes) | |
{ | |
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData); | |
var info = GetPropertyInformation(expression.Body); | |
if (info == null) return helper.DropDownListFor(expression, htmlAttributes); | |
var attr = info.GetAttribute<AllowedValuesAttribute>(true); | |
if (attr == null) return helper.DropDownListFor(expression, htmlAttributes); | |
IEnumerable<SelectListItem> items = | |
attr.Values.Select( | |
value => new SelectListItem() { Text = value, Value = value, Selected = value.Equals(metadata.Model) }); | |
return helper.DropDownListFor(expression, items, htmlAttributes); | |
} | |
/// <summary> | |
/// Gets property information | |
/// </summary> | |
/// <param name="expression">Expression to use</param> | |
/// <returns>Member info of property</returns> | |
public static MemberInfo GetPropertyInformation(Expression expression) | |
{ | |
var member = expression as MemberExpression; | |
if (member == null) | |
{ | |
var unary = expression as UnaryExpression; | |
if (unary != null && unary.NodeType == ExpressionType.Convert) | |
{ | |
member = unary.Operand as MemberExpression; | |
} | |
} | |
if (member != null && member.Member.MemberType == MemberTypes.Property) | |
{ | |
return member.Member; | |
} | |
return null; | |
} | |
/// <summary> | |
/// Attempts to get attribute from an object | |
/// </summary> | |
/// <typeparam name="T">Attribute to get</typeparam> | |
/// <param name="member">Member to get attribute from</param> | |
/// <param name="isRequired">Is the attribute required</param> | |
/// <returns>Required attribute</returns> | |
public static T GetAttribute<T>(this MemberInfo member, bool isRequired) where T : Attribute | |
{ | |
var attribute = member.GetCustomAttributes(typeof(T), false).SingleOrDefault(); | |
if (attribute == null && isRequired) return null; | |
return (T)attribute; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment