Skip to content

Instantly share code, notes, and snippets.

@odrix
Created February 15, 2013 14:26
Show Gist options
  • Save odrix/4960693 to your computer and use it in GitHub Desktop.
Save odrix/4960693 to your computer and use it in GitHub Desktop.
use data-annotation and ShortName with DisplayAttribute in ASP.NET MVC 4.0 (razor engine)
public class Employe
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Display(Name="Years of Experience", ShortName="Nb Exp")]
public int ExpYear { get; set; }
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Linq.Expressions.Internal;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
public static class HtmlHelpers
{
public static string DisplayShortNameFor<TModel, TValue>(this global::System.Web.Mvc.HtmlHelper<global::System.Collections.Generic.IEnumerable<TModel>> t, global::System.Linq.Expressions.Expression<global::System.Func<TModel,TValue>> exp)
{
CustomAttributeNamedArgument? DisplayName = null;
var prop = exp.Body as MemberExpression;
if (prop != null)
{
var DisplayAttrib = (from c in prop.Member.GetCustomAttributesData()
where c.AttributeType == typeof(DisplayAttribute)
select c).FirstOrDefault();
if(DisplayAttrib != null)
DisplayName = DisplayAttrib.NamedArguments.Where(d => d.MemberName == "ShortName").FirstOrDefault();
}
return DisplayName.HasValue ? DisplayName.Value.TypedValue.Value.ToString() : "";
}
}
@model IEnumerable<testMVC4.Models.Collaborateur>
@{ViewBag.Title = "Index";}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>@Html.DisplayNameFor(model => model.FirstName)</th>
<th>@Html.DisplayNameFor(model => model.LastName)</th>
<th>@Html.DisplayShortNameFor(model => model.ExpYear)</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>@Html.DisplayFor(modelItem => item.FirstName)</td>
<td>@Html.DisplayFor(modelItem => item.LastName)</td>
<td>@Html.DisplayFor(modelItem => item.ExpYear)</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
@Html.ActionLink("Details", "Details", new { id=item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
@bobquinn0801
Copy link

Thanks for the tip! This was a great start, but I found a few issues. It would cause an exception if @Html.DisplayShortNameFor was specified but there was no ShortName specified in the model.

I added code to handle this bug. If there is no ShortName specifed, then the Name is used. If no Name is specified, then the field's name is used.

Here is the code:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Linq.Expressions.Internal;
using System.Reflection;
using System.Web;
using System.Web.Mvc;

public static class HtmlHelpers
{
public static string DisplayShortNameFor<TModel, TValue>(this global::System.Web.Mvc.HtmlHelperglobal::System.Collections.Generic.IEnumerable t, global::System.Linq.Expressions.Expression<global::System.Func<TModel, TValue>> exp)
{
CustomAttributeNamedArgument? DisplayName = null;
var prop = exp.Body as MemberExpression;
if (prop != null)
{
var DisplayAttrib = (from c in prop.Member.GetCustomAttributesData()
where c.AttributeType == typeof(DisplayAttribute)
select c).FirstOrDefault();
if (DisplayAttrib != null)
{
DisplayName = DisplayAttrib.NamedArguments.Where(d => d.MemberName == "ShortName").FirstOrDefault();

            if (DisplayName.Value.TypedValue.Value == null)
            {
                DisplayName = DisplayAttrib.NamedArguments.Where(d => d.MemberName == "Name").FirstOrDefault();
            }


            if (DisplayName.Value.TypedValue.Value != null)
            {
                return DisplayName.Value.TypedValue.Value.ToString();
            }
            else
            {
                return "";
            }
        }
        else
        {
            return prop.Member.Name;
        }
    }
    return "";

}

}

@equiman
Copy link

equiman commented Jun 9, 2015

Thanks, help me a lot. I made an update. When don't found Short Name find the Name attribute.

public static class HtmlHelpers
{
public static string DisplayShortNameFor<TModel, TValue>(
this global::System.Web.Mvc.HtmlHelperglobal::System.Collections.Generic.IEnumerable t,
global::System.Linq.Expressions.Expression<global::System.Func<TModel, TValue>> exp)
{
CustomAttributeNamedArgument? DisplayName = null;
MemberExpression prop = exp.Body as MemberExpression;
if (prop != null)
{
CustomAttributeData DisplayAttrib = (
from c in prop.Member.GetCustomAttributesData()
where c.AttributeType == typeof(DisplayAttribute)
select c).FirstOrDefault();
if (DisplayAttrib != null)
{
DisplayName = DisplayAttrib.NamedArguments.Where(d => d.MemberName == "ShortName").FirstOrDefault();
if (DisplayName.Value.TypedValue.Value == null)
{
DisplayName = DisplayAttrib.NamedArguments.Where(d => d.MemberName == "Name").FirstOrDefault();
}
}
}
return (DisplayName.Value.TypedValue.Value != null) ? DisplayName.Value.TypedValue.Value.ToString() : "";
}
}

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