ASP.NET MVC의 Model 메타데이터 및 Model 템플릿:템플릿 가져오기 및 실행 정책

18225 단어
HtmlHelper나 HtmlHelper의 템플릿 방법을 호출하여 전체 모델이나 모델의 특정한 데이터 구성원을 특정한 모드(디스플레이 모드 또는 편집 모드)로 나타낼 때 미리 만들어진 모델 메타데이터를 대표하는 모델 메타데이터 대상을 통해 해당하는 템플릿을 찾을 수 있다.만약 템플릿이 사용자 정의 섹션 뷰에 대응한다면, 이 뷰만 실행하면 됩니다.기본 템플릿의 경우 해당 HTML을 직접 사용할 수 있습니다.이 글은 템플릿의 획득과 실행 메커니즘에 중심을 두고 있지만, 그 전에 DataType Attribute와 템플릿의 관계에 대해 토론하고자 합니다.[본문은 이미 에 동기화되었다.중]
1. DataTypeAttribute와 템플릿은 어떤 관계가 있습니까?
'모델 메타데이터'의 모델 메타데이터 정의에 대한 소개를 통해 DataType Attribute 특성을 통해 목표 요소에 설정된 데이터 유형이 최종적으로 모델 메타데이터를 나타내는 모델 메타데이터 대상의 DataTypeName 속성에 반영된다는 것을 알 수 있다.또한 Date,Time,Duration,Currency 등 일부 설정된 데이터 형식에 대해 DisplayFormatAttribute를 만들어서 ModelMetadata에 적용합니다.그렇다면 ModelMetadata의 DataTypeName 속성은 목표 요소의 최종 표현에 어떤 영향을 줍니까?
실제로 템플릿이 일치하는 과정에서 ModelMetadata의 DataTypeName 속성을 템플릿 이름으로 간주하기 때문에 아래 두 가지 형식의 모델 유형 정의는 같은 효과로 볼 수 있다.UIHintAttribute 특성을 통해 설정된 템플릿 이름과 DataTypeAttribute 특성을 통해 설정된 데이터 형식의 유일한 차이점은 우선순위가 높다는 점입니다.다시 말하면 UIHintAttribute와 DataTypeAttribute를 같은 데이터 구성원에게 동시에 적용하여 각각 템플릿 이름과 데이터 형식을 ABC와 123로 설정하면 사용자 정의 템플릿 123은 템플릿 ABC가 존재하지 않는 경우에만 사용된다.
   1: public class Model
   2: {
   3:     [DataType(DataType.Html)]
   4:     public string Foo { get; set; }
   5:  
   6:     [DataType(DataType.MultilineText)]
   7:     public string Bar { get; set; }
   8:  
   9:     [DataType(DataType.Url)]
  10:     public string Baz { get; set; }
  11: }
  12:  
  13: public class Model
  14: {
  15:     [UIHint("Html")]
  16:     public string Foo { get; set; }
  17:  
  18:     [UIHint("MultilineText")]
  19:     public string Bar { get; set; }
  20:  
  21:     [UIHint("Url")]
  22:     public string Baz { get; set; }
  23: }

인스턴스 데모: DataTypeName과 템플릿 이름의 동등성을 증명합니다.
DataTypeAttribute 특성을 통해 데이터 유형이 대상 요소를 시각적으로 표현하는 과정에서 템플릿 이름으로 간주된다는 것을 증명하기 위해 간단한 실례 설명을 드리겠습니다.이 인스턴스에서 다음과 같은 삼각형을 나타내는 데이터 유형인 Triangle을 정의했습니다. 속성 A, B, C는 Point 객체로 세 각도가 있는 좌표를 나타냅니다.
   1: public class Triangle
   2: {
   3:     [DataType("PointInfo")]
   4:      public Point A { get; set; }
   5:  
   6:     [DataType("PointInfo")]
   7:      public Point B { get; set; }
   8:  
   9:     [DataType("PointInfo")]
  10:     public Point C { get; set; }
  11: }
  12:  
  13: [TypeConverter(typeof(PointTypeConverter))]
  14: public class Point
  15: {
  16:     public double X { get; set; }
  17:     public double Y { get; set; }
  18:     public Point(double x, double y)
  19:     {
  20:         this.X = x;
  21:         this.Y = y;
  22:     }
  23:  
  24:     public static Point Parse(string point)
  25:     {
  26:         string[] split = point.Split(',');
  27:         if (split.Length != 2)
  28:         {
  29:             throw new FormatException("Invalid point expression.");
  30:         }
  31:         double x;
  32:         double y;
  33:         if (!double.TryParse(split[0], out x) ||!double.TryParse(split[1], out y))
  34:         {
  35:             throw new FormatException("Invalid point expression.");
  36:         }
  37:         return new Point(x, y);
  38:     }
  39: }
  40:  
  41: public class PointTypeConverter : TypeConverter
  42: {
  43:      public override bool CanConvertFrom(ITypeDescriptorContext context,Type sourceType)
  44:     {
  45:         return sourceType == typeof(string);
  46:     }
  47:  
  48:      public override object ConvertFrom(ITypeDescriptorContext context,CultureInfo culture, object value)
  49:     {
  50:         if (value is string)
  51:         {
  52:             return Point.Parse(value as string);
  53:         }
  54:         return base.ConvertFrom(context, culture, value);
  55:     }
  56: }

유형 Triangle과 Point의 정의에는 두 가지 주의할 점이 있다. 첫째, Triangle의 세 가지 A, B, C 속성에 DataTypeAttribute 특성을 적용하고 사용자 정의 데이터 유형을 PointInfo(PointInfo가 아님)로 설정했다.둘째, Point 유형에 TypeConverterAttribute 특성을 적용하고 TypeConverter 유형을 PointTypeConverter로 설정하며 후자는 문자열의 유형 전환을 지원한다.복잡한 유형(Complex Type)에 대한 앞의 설명을 통해 Triangle의 세 가지 속성을 복잡한 유형 구성원에서 간단한 유형 구성원으로 변환할 수 있습니다.Triangle의 이러한 세 속성은 데이터 멤버에 대한 Object 템플릿의 편리한 규칙에 따라 최종적으로 표시됩니다.
이제 Point 유형의 강력한 부분 View를 템플릿으로 만들고 PointInfo (DataType Attribute 특성을 통해 지정한 사용자 정의 데이터 형식과 일치) 라고 명명합니다.표시 모드에 대한 템플릿만 Point에 정의하므로 부분 View 파일을 Views\Shared\DisplayTemplates에 배치합니다.다음 코드 단편과 같이 Point 개체를 (X, Y) 형식으로 표시합니다.
   1: @model MvcApp.Models.Point
   2: (@Model.X, @Model.Y)

이제 기본 Home Ctroller를 만듭니다.아래 코드 단편과 같이 기본 Index 작업 방법에서 Triangle 객체가 만들어져 기본 View에 표시됩니다.
   1: public class HomeController : Controller
   2: {
   3:     public ActionResult Index()
   4:     {
   5:         Triangle triangle = new Triangle
   6:         {
   7:             A = new Point(1,2),
   8:             B = new Point(2,3),
   9:             C = new Point(3,4)
  10:         };
  11:         return View(triangle);
  12:     }
  13: }

다음은 대응하는 View의 정의입니다. 이것은 모델 유형이 Triangle인 강력한 유형의 View입니다. HtmlHelper의 DisplayModel 방법만 호출하면 모델의 Triangle 대상으로 디스플레이 모델로 나타날 것입니다.
   1: @model MvcApp.Models.Triangle
   2: @Html.DisplayForModel()

이 웹 애플리케이션을 실행하면 브라우저에서 아래 그림과 같이 표시되며 Triangle 객체의 A, B, C 속성으로 표시되는 세 각도의 좌표가 PointInfo 템플릿에 정의된 대로 표시됩니다.
2. 템플릿의 획득과 집행
HtmlHelper나 HtmlHelper의 템플릿 방법을 호출하여 전체 모델이나 모델의 특정한 데이터 구성원을 특정한 모드(디스플레이 모드 또는 편집 모드)로 나타낼 때 미리 만들어진 모델 메타데이터를 대표하는 모델 메타데이터 대상을 통해 해당하는 템플릿을 찾을 수 있다.만약 템플릿이 사용자 정의 섹션 뷰에 대응한다면, 이 뷰만 실행하면 됩니다.기본 템플릿의 경우 해당 HTML을 직접 사용할 수 있습니다.
모델 메타데이터에 따라 목표 템플릿에 대한 해석은 전체 템플릿 방법의 집행 절차에서 가장 핵심적인 부분이자 본 토론의 중점이다.HtmlHelper에 대한 확장 방법인 DisplayFor를 예로 들어 표현식expression을 통해 얻은 모델 대상이 어떻게 디스플레이 모드로 나타나는지 살펴봅시다.
   1: public static class DisplayExtensions
   2: {
   3:     public static MvcHtmlString DisplayFor(this HtmlHelper html, Expression> expression, string templateName);
   4: }

DisplayFor가 호출되었을 때, 매개 변수expression을 통해 표시된 모델 획득 표현식이 특정한 속성에 대한 것이라면 속성 이름이 획득됩니다.그리고 표현식을 실행하면 모델로서의 대상을 얻을 수 있습니다. 이 대상은 속성 이름 (있을 경우) 과 함께 모델의 메타데이터를 나타내는 메타데이터 대상에 사용됩니다.그런 다음 Metadatadata 객체에 따라 다음과 같이 섹션 템플릿의 View 이름을 나타내는 일련의 목록이 표시됩니다.
  • 매개 변수인templateName에서 입력한 템플릿 이름입니다(비어 있지 않은 경우).
  • Metadatadata의 TemplateHint 속성 값(비어 있지 않은 경우).
  • Metadatadata의 DataTypeName 속성 값(비어 있지 않은 경우).
  • 모델 대상의 실제 유형이 비공값 유형이면 이 유형 이름은 템플릿 View 이름으로 한다.그렇지 않으면 기본 (Underlying) 형식 이름이 템플릿 뷰 이름으로 지정됩니다. (예를 들어 int? 형식에 대해서는 Int32를 템플릿 뷰 이름으로 지정합니다.)
  • 모델 대상의 실제 유형이 비복잡한 유형이면 String 템플릿을 사용합니다(비복잡한 유형은 String 유형과의 전환을 실현할 수 있기 때문에 String으로 변환하여 나타낼 수 있습니다).
  • 모델의 성명 유형이 인터페이스인 경우 이 인터페이스가 IEnuerable에서 계승되면 Collection 템플릿을 사용합니다.
  • 모델 선언 유형이 인터페이스인 경우 Object 템플릿을 사용합니다.
  • 모델 성명 유형이 인터페이스 유형이 아니라면 그 유형 계승 관계에 따라 Object 유형을 거슬러 올라가 유형 이름을 각각 템플릿 View 이름으로 한다.선언 유형이 IEnuerable 인터페이스를 구현한 경우 마지막 Object를 Collection으로 바꿉니다.

  • 얻은 이 표시 목록은 선후 순서에 따라 모든 요소를 편리하게 할 것이다.특정 템플릿 View 이름을 나타내는 문자열은 나타나는 패턴에 따라 지정된 경로(표시 모드와 편집 모드는 각각 "/Display Templates/{Template Name}"와 "/Editor Templates/{Template Name}")에서 템플릿을 정의하는 View를 찾습니다.이러한 뷰가 있는 경우 뷰를 직접 실행하고 로 돌아갑니다.사용자 정의 템플릿 섹션 View를 찾을 수 없는 경우 템플릿 이름에 따라 기본 템플릿 목록에서 찾고, 이름이 일치하는 기본 템플릿이 있는 경우 기본 템플릿에 해당하는 HTML을 반환합니다.기본 템플릿 목록의 이름이 지정한 이름과 일치하지 않으면 다음 교체에 들어갑니다.
    ASP.NET MVC의 Model 메타데이터 및 Model 템플릿:미리 정의된 템플릿 ASP.NET MVC의 Model 메타데이터와 Model 템플릿:템플릿 획득 및 실행 정책 ASP.NET MVC의 Model 메타데이터와 Model 템플릿: ASP에 ListControl을 도입합니다.NET MVC

    좋은 웹페이지 즐겨찾기