.NET TIPS

[ASP.NET MVC]カスタムのビュー・エンジンを利用するには?(実装編)[3.5、C#、VB]

山田 祥寛
2010/01/28

 「TIPS:NVelocityをビュー・エンジンとして利用するには?」では、MVC Contribに含まれるNVelocityを利用したが、もちろん、出来合いのビュー・エンジンを組み込むばかりではない。必要に応じて、ビュー・エンジンを自作して組み込むこともできる。

 本稿では、ビュー・エンジンを自作する例として、XSLT(eXtensible Stylesheet Language Transformations)スタイルシートをビュー・スクリプトとして利用するXsltViewEngineエンジンを作成してみよう。

 XsltViewEngineエンジンは、アクション・メソッドからXMLデータ(System.Xml.Linq.XDocumentオブジェクト)を受け取り、これを.xsltファイルに整形した結果を返すためのビュー・エンジンである。

 それではさっそく、具体的な実装の手順を見ていこう。

■1. ビュー・クラスを実装する

 ビュー・エンジンと一口にいっても、その実体は、(狭義での)ビュー・エンジンとビュー・クラスとに分類できる。

 ビュー・クラスとは、渡されたモデルやビュー変数をビュー・スクリプトに割り当て、最終的な出力を生成するためのクラス、一方、(狭義での)ビュー・エンジンは、アクション・メソッドに応じて対応するビュー・スクリプトを検索するとともに、これをビュー・クラスに引き渡す役割を持ったクラスである。

 まずは、ビュー処理の中核となるビュー・クラスから見ていくことにしよう。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
using System.Xml.Xsl;

namespace MvcAppCs.Extensions {
  public class XsltView : IView { 

    // ビュー・スクリプトのパスを格納するプライベート変数
    private String _path;
   
    // ビュー・スクリプトのパスを初期化(コンストラクタ)
    public XsltView(String path) {
      this._path = path;
    }
   
    // ビュー・スクリプトを解析し、最終的な出力を生成
    public void  Render(
        ViewContext viewContext, System.IO.TextWriter writer) { 

      // XSLT変換のためのXsltCompiledTransformオブジェクトを生成
      var xslt = new XslCompiledTransform();

      // 変数_pathで指定されたスタイルシートを読み込み
      xslt.Load(viewContext.HttpContext.Server.MapPath(this._path));

      // モデルとして渡されたXML文書(XDocumentオブジェクト)を取得
      var doc = (XDocument)viewContext.ViewData.Model;

      // 変換処理を実行&結果を出力
      xslt.Transform(doc.CreateReader(), new XsltArgumentList(), writer);
    }
  }
}
Imports System.Xml.Xsl

Public Class XsltView : Implements IView 

  ' ビュー・スクリプトのパスを格納するプライベート変数
  Private _path As String

  ' ビュー・スクリプトのパスを初期化(コンストラクタ)
  Public Sub New(ByVal path As String)
    Me._path = path
  End Sub

  ' ビュー・スクリプトを解析し、最終的な出力を生成
  Public Sub Render(ByVal viewContext As ViewContext, _
      ByVal writer As System.IO.TextWriter) Implements IView.Render 

    ' XSLT変換のためのXsltCompiledTransformオブジェクトを生成
    Dim xsl As New XslCompiledTransform()

    ' 変数_pathで指定されたスタイルシートを読み込み
    xsl.Load(viewContext.HttpContext.Server.MapPath(Me._path))

    ' モデルとして渡されたXML文書(XDocumentオブジェクト)を取得
    Dim doc = DirectCast(viewContext.ViewData.Model, XDocument)

    ' 変換処理を実行&結果を出力
    xsl.Transform( _
      doc.CreateReader(), New XsltArgumentList(), writer)
  End Sub
End Class
ビュー・スクリプトを解析&最終的な出力を生成するためのコード(上がXsltView.cs、下がXsltView.vb)

 ビュー・エンジンは、IViewインターフェイスを介してビューを呼び出すため、すべてのビュー・クラスは必ずIViewインターフェイスを実装していなければならない()。

 IView実装クラスでは、最低限、Renderメソッドを実装する必要がある()。Renderメソッドは、アクション・メソッドから与えられたビュー変数やモデルをビュー・スクリプトに割り当て、最終的な出力を生成するためのメソッドである。

[構文]Renderメソッド
void  Render(ViewContext viewContext, TextWriter writer)

viewContext:ビュー描画に関するコンテキスト情報(ビュー変数、モデルなどへのアクセス手段)
writer:最終的な出力結果を出力するためのライター

 ここでは、XSLTスタイルシートをビュー・スクリプトとして処理したいので、XsltCompiledTransformクラス(System.Xml.Xsl名前空間)を使用している。

 XsltCompiledTransformオブジェクトを利用するには、LoadメソッドでXSLT変換に使用する.xsltファイルを読み込んでおく必要がある。後述するが、.xsltファイル(ビュー・スクリプト)のパスは、ビュー・クラスをインスタンス化する際にビュー・エンジンから渡され、プライベート変数_pathにセットされているはずである。.xsltファイルを読み込めてしまえば、あとはTransformメソッドで変換処理を行うだけである。

[構文]Transformメソッド
void Transform (XmlReader input, XsltArgumentList args, TextWriter results)

input:変換対象となるXML文書 args:スタイルシートのパラメータ
results:変換結果を出力するためのライター

 変換対象のXML文書(XDocumentオブジェクト)は、Renderメソッドの引数viewContextからViewData.Modelプロパティにアクセスすることで取得できる(ここではTransformメソッドに引き渡すために、XDocument.CreateReaderメソッドで、XML文書を読み込むためのXmlReaderオブジェクトを取得している)。

 引数argsは不要なので、ここでは空のXsltArgumentListオブジェクトを、引数resultsにはRenderオブジェクトに渡されたTextWriterオブジェクトwriterをそのまま引き渡している。変数writerにはResponse.Outputプロパティがセットされているので*1、スタイル変換の結果はクライアントに出力されることになる。

*1 TextWriterオブジェクトはViewResultオブジェクト(ビュー・スクリプトを処理するためのActionResultオブジェクト)が内部的に生成している。まずは、アプリケーション開発者が意識する必要はないだろう。

■2. ビュー・エンジンを実装する

 前述したように、ビュー・クラスはあくまで渡されたビュー・スクリプトを処理し、その結果を出力するだけのクラスである。ビュー・クラスを動作するには、必要なビュー・スクリプトを検索し、ビュー・クラスに引き渡すための(狭義の)ビュー・エンジンを定義しなければならない。

 ビュー・エンジンを定義するには、IViewEngineインターフェイス(System.Web.Mvc名前空間)を実装したクラスを用意する必要がある。もっとも、一からIViewEngineインターフェイスを実装するのはそれなりに大変な作業である。ビュー・スクリプトをファイル・システム上で管理することを前提とするならば、すでにIViewEngine実装クラスとして提供されているVirtualPathProviderViewEngineクラス(System.Web.Mvc名前空間)を利用するのが簡単だろう。

 VirtualPathProviderViewEngineクラスでは、ファイル・システムからビュー・スクリプトを検索する基本的な手段をすでに実装しているので、検索先のパスなど最低限のコードを追加するだけで、ビュー・エンジンを実装できる。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcAppCs.Extensions {
  public class XsltViewEngine : VirtualPathProviderViewEngine {

    // ビュー・スクリプトの検索先を定義(コンストラクタ)
    public XsltViewEngine() {
      this.ViewLocationFormats =
      this.PartialViewLocationFormats = new[] {
        "~/Views/{1}/{0}.xslt",
        "~/Views/Shared/{0}.xslt"
    };
  }

    // ビューを生成するためのメソッド
    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) {
      return new XsltView(viewPath);
    }

    // 部分ビューを生成するためのメソッド
    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) {
      return new XsltView(partialPath);
    }
  }
}
Public Class XsltViewEngine : Inherits VirtualPathProviderViewEngine

  ' ビュー・スクリプトの検索先を定義(コンストラクタ)
  Public Sub New()
    Me.ViewLocationFormats = New String() { _
        "~/Views/{1}/{0}.xslt", _
        "~/Views/Shared/{0}.xslt" _
      }
    Me.PartialViewLocationFormats = Me.ViewLocationFormats
  End Sub

  ' ビューを生成するためのメソッド
  Protected Overrides Function CreatePartialView(ByVal controllerContext As ControllerContext, ByVal partialPath As String) As IView
    Return New XsltView(partialPath)
  End Function

  ' 部分ビューを生成するためのメソッド
  Protected Overrides Function CreateView(ByVal controllerContext As ControllerContext, ByVal viewPath As String, ByVal masterPath As String) As IView
    Return New XsltView(viewPath)
  End Function

End Class
XsltViewEngineビュー・エンジンを実装するコード(上がXsltViewEngine.cs、下がXsltViewEngine.vb)

 VirtualPathProviderViewEngineクラスのViewLocationFormatsプロパティはビュー・スクリプトの検索パスを、PartialViewLocationFormatsプロパティは部分ビュー・スクリプトの検索パスを、それぞれ優先順に文字列配列で表すものだ。では、これらのプロパティに対して、

(1)~/Views/{1}/{0}.xslt
(2)~/Views/Shared/{0}.xslt

を渡しているので、この順番でビュー・スクリプトを検索することになる({0}、{1}はそれぞれコントローラ名とアクション名を表す)。XsltViewEngineクラスでは、ビュー・スクリプトも部分ビュー・スクリプトも特に区別はしないので、ViewLocationFormats/PartialViewLocationFormatsいずれにも同じ値をセットしている。

 あとは、CreateView/CreatePartialViewメソッドをオーバライドするだけだ()。これらはそれぞれビュー、部分ビューを生成するためのメソッドである。ここでは、いずれのメソッドも、ビューの実体であるXsltViewオブジェクトを生成し、戻り値として返している。

 以上、今回はビュー・エンジンを実装するための手順について解説した。ここで自作したビュー・エンジンを実際に利用する方法については、後日公開予定の「TIPS:[ASP.NET MVC]カスタムのビュー・エンジンを利用するには?(活用編)」で解説する。End of Article

利用可能バージョン:.NET Framework 3.5
カテゴリ:Webフォーム 処理対象:ASP.NET MVC
関連TIPS:NVelocityをビュー・エンジンとして利用するには?

この記事と関連性の高い別の.NET TIPS
[ASP.NET MVC]カスタムのビュー・エンジンを利用するには?(活用編)
[ASP.NET MVC]NVelocityをビュー・エンジンとして利用するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間