2013. 9. 11. 16:00

'레이저(Razor)'같은 뷰엔진에서  몇몇 속성은 이미 만들어져 있는 메서드를 가지고 출력이 가능합니다.

대표적인 메서드가 '@Html.DisplayNameFor'나 ''@Html.ValidationMessageFor같은 것들입니다.

 

문제는 정된 메서드만으로는 모든 속성을 표시할 수 없다는 점입니다.

 

 

1. 문제의 시작

다음과 같이 모델을 선언합시다.

/// <summary>
/// 단어
/// </summary>
[DisplayName("단어")]
[Required(ErrorMessage = "단어를 적어 주세요.")]
[Display(Description = "문제로 쓰일 단어 입니다.")]
public string Word { get; set; }

 

위 코드를 뷰로 보내서 바인딩한다면 '@Html.DisplayNameFor'를 사용하면 'DisplayName'으로 지정한 문자열이 출력됩니다.

 

 

너무나 당연한 이야기입니다.

 

그러면......

'Description'으로 설정된 속성은 어떻게 가지고 와야 할까요?

 

막연히 생각해 보면 '@Html.DisplayFor'로 어찌어찌하면 될 것 같은데 아무리 레퍼런스를 확인해도 답이 없습니다.

 

 

2. 해결 방법

가장 좋은 해결 방법은 '@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'속성을 받아 올 수 있습니다.

 

 

3. 테스트

적절한 위치에 확장 메서드를 만들고 아래 코드를 넣습니다.

(참고 : [.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가 없어서입니다-_-;;;)

 

컨트롤러에서 이러한 속성들을 받기 위해서는 같은 메서드가 있어야 합니다.

단지 모양이 다른 메서드가 필요하죠.

 

이건 다른 포스팅에서 알아보겠습니다.