RazorEngine.Compile() が匿名型を他の型とは異なる方法で扱っているように見えることに気付きました。たとえば、次のコードを考えてみましょう。
public static void Main()
{
try {
var model = new { s = default(string) };
RazorEngine.Razor.Compile("@Model.s.Length", model.GetType(), "a");
RazorEngine.Razor.Run(model, "a");
} catch (Exception ex) {
Console.WriteLine(ex); // RuntimeBinderException (Cannot perform runtime binding on a null reference)
}
try
{
var model = "";
RazorEngine.Razor.Compile(@"@Model.Length", model.GetType(), "b");
RazorEngine.Razor.Run(default(string), "b");
} catch (Exception ex) {
Console.WriteLine(ex); // NullReferenceException
}
try
{
var model = Tuple.Create(default(string));
RazorEngine.Razor.Compile(@"@Model.Item1.Length", model.GetType(), "c");
RazorEngine.Razor.Run(model, "c");
} catch (Exception ex) {
Console.WriteLine(ex); // NullReferenceException
}
try
{
var model = new Internal();
RazorEngine.Razor.Compile(@"@Model.S.Length", model.GetType(), "d");
RazorEngine.Razor.Run(model, "d");
} catch (Exception ex) {
Console.WriteLine(ex); // TemplateCompilationException (type Internal is not visible)
}
}
internal class Internal {
public string S { get; set; }
}
私の理解は次のとおりです。匿名型は内部であるため、通常、Razor はそれらを処理しません。ただし、Razor は代わりに動的テンプレートを生成することにより、匿名型の特別なサポートを提供します。
したがって、2 つの質問があります。(1) この動作に対する私の理解は正しいですか? (2) かみそりに匿名モデルの厳密に型指定されたテンプレートを出力させる方法はありますか?