ASP.NET MVC-自分のViewEngineをカスタマイズ
9734 ワード
ASP.NET MVCがこんなに長く出てきたのに、なぜすべてのViewがViewディレクトリの下に置かれているのかと疑問に思っている.Sharedフォルダの下のページを共有できるのはなぜですか?どうしてPageは*.cshtmlは、*.aspx?
実は上のいくつかの問題をまとめると、ビューエンジンの効果です.
従来のASP.NETでは、まだViewEngineの概念がないかもしれません.Web Fromでは、実装PageがIHttpHanlderのインタフェースを実現するため、Pageは応答の処理クラスであり、ビューのレンダリングクラスでもある.ASP.NET MVCでは,ビューの概念が抽象化され,エンジンを試みる概念もインタフェースとして抽象化される.
まず、IViewEngineインタフェースの定義を見てみましょう.
[csharp] view plain copy print ?
namespace System.Web.Mvc {
public interface IViewEngine {
ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache); ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
void ReleaseView(ControllerContext controllerContext, IView view); }
}
合計3つの関数をまとめると、Find&Releaseという2つの機能があります.
デフォルトでは、ASP.NET MVCには、WebFormViewEngineとRazorViewEngineの2つのビューエンジンがあります.
[csharp] view plain copy print ?
namespace System.Web.Mvc {
public static class ViewEngines {
private static readonly ViewEngineCollection _engines = new ViewEngineCollection {
new WebFormViewEngine(), new RazorViewEngine(),
};
public static ViewEngineCollection Engines {
get { return _engines; } }
} }
だからASP.NET MVC既支持*.aspx、また*.cshtmlの理由です(個人的にはRazorViewを使うことが決まっているなら、WebFormViewを削除したほうが性能に役立つかもしれないと思います).
では、なぜすべてのビューがViewsディレクトリの下に置かれているのでしょうか.これはRazorViewnginesの賜物です.
次はRazorViewEngineのコンストラクション関数です.
[csharp] view plain copy print ?
public RazorViewEngine(IViewPageActivator viewPageActivator) : base(viewPageActivator)
{ AreaViewLocationFormats = new[]
{ "~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml", "~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml" };
AreaMasterLocationFormats = new[] {
"~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.vbhtml"
}; AreaPartialViewLocationFormats = new[]
{ "~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml", "~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml" };
ViewLocationFormats = new[]
{ "~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml" };
MasterLocationFormats = new[] {
"~/Views/{1}/{0}.cshtml", "~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml"
}; PartialViewLocationFormats = new[]
{ "~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml" };
FileExtensions = new[]
{ "cshtml",
"vbhtml", };
}
すべてのアドレスパスがフォーマットされているのはよく知られているのではないでしょうか.ここでリストを使わずに配列を使う理由については、配列のアドレス効率がもっと高く、遍歴速度が速いと思います.
さあ、「元凶」を探したら、おとなしく言うことを聞いて、どこへでも行かせてください.
[csharp] view plain copy print ?
namespace MvcApplicatin.Web.Mvc.ViewEngine {
public sealed class CustomViewEngine : RazorViewEngine {
public CustomViewEngine()
{ ViewLocationFormats = new[]
{ "~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml", "~/CustomViewLocation/{1}/{0}.cshtml"
}; }
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) {
return base.FindView(controllerContext, viewName, masterName, useCache); }
} }
私が開発言語を使っているのはC#で、ビューはRazorなので、CustomViewLocationの下のビューを見つけるためにViewLocationFormatを少し修正しました.
次は簡単です.元のビューエンジンを空にして、自分のビューエンジンをロードすればいいだけです.
[csharp] view plain copy print ?
protected void Application_Start() {
AreaRegistration.RegisterAllAreas();
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes);
}
実は上のいくつかの問題をまとめると、ビューエンジンの効果です.
従来のASP.NETでは、まだViewEngineの概念がないかもしれません.Web Fromでは、実装PageがIHttpHanlderのインタフェースを実現するため、Pageは応答の処理クラスであり、ビューのレンダリングクラスでもある.ASP.NET MVCでは,ビューの概念が抽象化され,エンジンを試みる概念もインタフェースとして抽象化される.
まず、IViewEngineインタフェースの定義を見てみましょう.
[csharp] view plain copy print ?
namespace System.Web.Mvc
public interface IViewEngine
ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
void ReleaseView(ControllerContext controllerContext, IView view);
}
namespace System.Web.Mvc
{
public interface IViewEngine
{
ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
void ReleaseView(ControllerContext controllerContext, IView view);
}
}
合計3つの関数をまとめると、Find&Releaseという2つの機能があります.
デフォルトでは、ASP.NET MVCには、WebFormViewEngineとRazorViewEngineの2つのビューエンジンがあります.
[csharp] view plain copy print ?
namespace System.Web.Mvc
public static class ViewEngines
private static readonly ViewEngineCollection _engines = new ViewEngineCollection
new WebFormViewEngine(),
};
public static ViewEngineCollection Engines
get { return _engines; }
}
namespace System.Web.Mvc
{
public static class ViewEngines
{
private static readonly ViewEngineCollection _engines = new ViewEngineCollection
{
new WebFormViewEngine(),
new RazorViewEngine(),
};
public static ViewEngineCollection Engines
{
get { return _engines; }
}
}
}
だからASP.NET MVC既支持*.aspx、また*.cshtmlの理由です(個人的にはRazorViewを使うことが決まっているなら、WebFormViewを削除したほうが性能に役立つかもしれないと思います).
では、なぜすべてのビューがViewsディレクトリの下に置かれているのでしょうか.これはRazorViewnginesの賜物です.
次はRazorViewEngineのコンストラクション関数です.
[csharp] view plain copy print ?
public RazorViewEngine(IViewPageActivator viewPageActivator)
{
{
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
AreaMasterLocationFormats = new[]
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
};
{
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
{
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.vbhtml"
MasterLocationFormats = new[]
"~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml",
};
{
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.vbhtml"
{
"vbhtml",
}
public RazorViewEngine(IViewPageActivator viewPageActivator)
: base(viewPageActivator)
{
AreaViewLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
AreaMasterLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
AreaPartialViewLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
ViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
MasterLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
PartialViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
FileExtensions = new[]
{
"cshtml",
"vbhtml",
};
}
すべてのアドレスパスがフォーマットされているのはよく知られているのではないでしょうか.ここでリストを使わずに配列を使う理由については、配列のアドレス効率がもっと高く、遍歴速度が速いと思います.
さあ、「元凶」を探したら、おとなしく言うことを聞いて、どこへでも行かせてください.
[csharp] view plain copy print ?
namespace MvcApplicatin.Web.Mvc.ViewEngine
public sealed class CustomViewEngine : RazorViewEngine
{
{
"~/Views/Shared/{0}.cshtml",
};
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
return base.FindView(controllerContext, viewName, masterName, useCache);
}
namespace MvcApplicatin.Web.Mvc.ViewEngine
{
public sealed class CustomViewEngine : RazorViewEngine
{
public CustomViewEngine()
{
ViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml",
"~/CustomViewLocation/{1}/{0}.cshtml"
};
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
return base.FindView(controllerContext, viewName, masterName, useCache);
}
}
}
私が開発言語を使っているのはC#で、ビューはRazorなので、CustomViewLocationの下のビューを見つけるためにViewLocationFormatを少し修正しました.
次は簡単です.元のビューエンジンを空にして、自分のビューエンジンをロードすればいいだけです.
[csharp] view plain copy print ?
protected void Application_Start()
AreaRegistration.RegisterAllAreas();
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
RegisterGlobalFilters(GlobalFilters.Filters);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}