'레이저(Razor)'같은 뷰엔진에서 몇몇 속성은 이미 만들어져 있는 메서드를 가지고 출력이 가능합니다.
대표적인 메서드가 '@Html.DisplayNameFor'나 ''@Html.ValidationMessageFor같은 것들입니다.
문제는 정된 메서드만으로는 모든 속성을 표시할 수 없다는 점입니다.
다음과 같이 모델을 선언합시다.
/// <summary>
/// 단어
/// </summary>
[DisplayName("단어")]
[Required(ErrorMessage = "단어를 적어 주세요.")]
[Display(Description = "문제로 쓰일 단어 입니다.")]
public string Word { get; set; }
위 코드를 뷰로 보내서 바인딩한다면 '@Html.DisplayNameFor'를 사용하면 'DisplayName'으로 지정한 문자열이 출력됩니다.
너무나 당연한 이야기입니다.
그러면......
'Description'으로 설정된 속성은 어떻게 가지고 와야 할까요?
막연히 생각해 보면 '@Html.DisplayFor'로 어찌어찌하면 될 것 같은데 아무리 레퍼런스를 확인해도 답이 없습니다.
가장 좋은 해결 방법은 '@Html.DisplayNameFor'를 변형하는 것입니다.
하지만 'Html.DisplayNameFor'의 구현내용은 보이지 않으므로 구글링을 통해 구현 방법을 알아봅시다.
구글링을 해보면 'Html.DisplayNameFor'를 확장 메서드를 이용하여 커스텀하는 방법이 많이 나옵니다.
(참고 : stackoverflow - Get [DisplayName] attribute of a property in strongly-typed way )
여기에 우리가 원하는 답이 있습니다.
using System.Linq.Expressions;
namespace System.Web.Mvc.Html
{
public static class DisplayNameExtensions
{
public static string GetDisplayName<TModel, TProperty>(this HtmlHelper html, TModel model, Expression<Func<TModel, TProperty>> expression)
{
return ModelMetadata.FromLambdaExpression<TModel, TProperty>
(expression
, new ViewDataDictionary<TModel>(model)
).DisplayName;
}
}
}
이것이 '@Html.DisplayNameFor'를 구현한 것입니다.
우리는 여기서 'DisplayName'대신 'Description'로 바꾸면 'Description'속성을 받아 올 수 있습니다.
적절한 위치에 확장 메서드를 만들고 아래 코드를 넣습니다.
(참고 : [.Net] 확장 메서드(Extension Methods))
using System.Linq.Expressions;
namespace System.Web.Mvc.Html
{
public static class DisplayDescriptionExtensions
{
public static string GetDescription<TModel, TProperty>(this HtmlHelper html, TModel model, Expression<Func<TModel, TProperty>> expression)
{
return ModelMetadata.FromLambdaExpression<TModel, TProperty>
(expression
, new ViewDataDictionary<TModel>(model)
).Description;
}
}
}
이제 뷰에서 '@Html.GetDescription(Model, model => model.Word )' 를 통해 'Description'를 받아올 수 있습니다.
이 방법을 통해서 커스텀한 속성도 불러올 수 있습니다.
문제는 비하인드 코드지요 ㅋㅋㅋㅋ
비하인드코드인 컨트롤러에서는 이렇게 선언한 메서드를 호출할 수 없습니다.
(HtmlHelper가 없어서입니다-_-;;;)
컨트롤러에서 이러한 속성들을 받기 위해서는 같은 메서드가 있어야 합니다.
단지 모양이 다른 메서드가 필요하죠.
이건 다른 포스팅에서 알아보겠습니다.