質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Razor

RazorはASP.NET Web PagesとASP.NET MVCで使われているビュー・エンジンです。HTMLマークアップとC#またはVisual Basicのコードに対応しています。マークアップとコードの間の切り替えは"@"で記されています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

1284閲覧

Razor.Engineがまれにエラーになる

propg

総合スコア113

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Razor

RazorはASP.NET Web PagesとASP.NET MVCで使われているビュー・エンジンです。HTMLマークアップとC#またはVisual Basicのコードに対応しています。マークアップとコードの間の切り替えは"@"で記されています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2018/03/23 11:32

WPFアプリからCSV出力、取り込み、参照用HTML生成などの処理にRazorEngineのテンプレート機能を使っています。
出力内容を別ファイルで管理できるので、とても便利です。

c#

1var template = Path.Combine("c:\aaaa\bbb\, "Template1.cshtml"); 2var templateHtmlText = File.ReadAllText(template); 3 4var htmlBody = Engine.Razor.RunCompile(templateHtmlText, "templateKey", typeof(Models.TestModel), ModelObj); 5

おおむね問題ありませんが、以下の例外が発生することがあります。

RazorEngine.Templating.TemplateCompilationException: Errors while compiling a Template. Please try the following to solve the situation: * If the problem is about missing/invalid references or multiple defines either try to load the missing references manually (in the compiling appdomain!) or Specify your references manually by providing your own IReferenceResolver implementation. See https://antaris.github.io/RazorEngine/ReferenceResolver.html for details. Currently all references have to be available as files! * If you get 'class' does not contain a definition for 'member': try another modelType (for example 'null' to make the model dynamic). NOTE: You CANNOT use typeof(dynamic) to make the model dynamic! Or try to use static instead of anonymous/dynamic types. More details about the error: - error: (0, 0) 型 'System.Attribute' が参照されていないアセンブリで定義されています。アセンブリ 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' への参照を追加してください。 Temporary files of the compilation can be found in (please delete the folder): C:\Users\kensa_byouri\AppData\Local\Temp\RazorEngine_jdkwz34l.low

1度発生すると、何度呼び出してもこのエラーになります。
ですが、一度プログラムを終了して、再度呼び出してみるとエラーは起こらなくなります。
その後そのパソコンではほとんど発生しません。
新しいパソコンで初めて実行する際に起こりやすいような気がしています。

参照されていないのなら毎回エラーになるはずですが、たまになるのはなぜ?

タイミングが分からず対応の糸口が分かっていません。
原因や解決策など分かる方おりませんでしょうか。

※この処理では、プログラム実行後初回呼出時に毎回コンパイルが行われ、TEMPフォルダ内に「RazorEngine_xxxxxx」の名前でフォルダが作成されます。
起動後の初回が毎回遅いのですが、このコンパイルしたDLL?を参照して毎回コンパイルせずにすればよいと思うのですが、そんなことは可能でしょうか。
(cshtmlが更新されていなければ、コンパイルせずにコンパイル済みdllのテンプレートを使用する)
そうすれば、コンパイルエラーもほぼ起こらないと思うのですが。。。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

症状としてはこちらのIssueと同じでしょうか
assembly 'System.Runtime' is needed to compile · Issue #416 · Antaris/RazorEngine

ここには発生例と回避策として以下の内容が書かれています。

In my case it was because of .winmd files in my app domain loaded assemblies.
They have version 255.255.255.255 of mscorlib ref (http://screencast.com/t/xZlsNAoKKga)
I solved it by ignoring .winmd files in custom ReferenceResolver
https://antaris.github.io/RazorEngine/ReferenceResolver.html

C#

private class MyIReferenceResolver : IReferenceResolver
{
public IEnumerable<CompilerReference> GetReferences(TypeContext context, IEnumerable<CompilerReference> includeAssemblies)
{
return new UseCurrentAssembliesReferenceResolver()
.GetReferences(context, includeAssemblies)
.Where(f => !f.GetFile().EndsWith(".winmd"));
}
}
// カスタムReferenceResolverの使用例
var config = new TemplateServiceConfiguration { Debug = true, ReferenceResolver = new MyIReferenceResolver() };
Engine.Razor = RazorEngineService.Create(config);
var template = "Hello @Model.Name, welcome to RazorEngine!";
var text = Engine.Razor.RunCompile(template, "templateKey", null, new { Name = "World"});

.winmdファイルがAppDomainにロードされている場合に発生するため、カスタムReferenceResolverを作成してコンパイラに渡すアセンブリ参照から.winmdファイルを取り除くという方法で対応しているようです。 EcoDriveさんの事例では、毎回ではなくたまに発生し、1回発生すると続けて発生してプログラムを終了すると発生しなくなるとのことでした。 アセンブリは起動時にすべて読み込まれるのではなく必要になったタイミングで初めて読み込まれるので、テンプレートの初回呼び出しが.winmdファイルが読み込まれる何らかの処理の前に行われているかどうかによってエラー発生の有無が変わっていることが考えられます。

投稿2018/03/27 14:00

evin101

総合スコア92

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

propg

2018/03/29 05:27

evin101さん 回答ありがとうございます。 現象としてはずばりこの内容ではないかと思いました。 この例の通り実装してみて動作させてみました。 すると、ある特定のパソコン(おそらくこの事象に当てはまる条件になっているパソコン)で動かした際、「キューがありません」(エラー内容うろ覚え)のようなエラーが発生しました。 さらにその後、ブルースクリーンになりパソコンが強制再起動となりました。 何度か試しましたが同じ状態になり、急いで元に戻しました。 ReferenceResolverの指定をなくせば今まで通り動作したため、追加した分の問題ではないかと思います。.winmdを全部除外してはいけないのか?? なぜWindowsの動作自体にまで影響が出たのか分かっていませんが、とりあえず提示いただいたサイトでコメントされていた別の方法「System.Runtimeをアセンブリリストに追加する」で実装して再度試してみたいと思います。
evin101

2018/03/29 16:42

逆に問題が発生してしまったようで申し訳ありません。 ちなみに関係ないかもしれませんが、前述のコードのようにテンプレートのコンパイルの際に毎回 RazorEngineService.Createをしてしまうと、キャッシュが効かずに毎回新しいテンプレートのアセンブリが作成され読み込まれるため注意が必要です。
propg

2018/04/10 10:41

いえいえ、有益な情報助かりました。 RazorEngineService.Createは起動後app.xaml.cs等で1回呼んでおけばよいのでしょうか。 「キューがありません」のエラーは、SendKeysでTABを呼んでいる処理があるのですが、そこで発生していました。なぜか不明ですが、以前からたまにエラーは発生していたため、SendKeysはすべて削除しました。 今のところ致命的エラーは発生してないのですが、そもそもいつ発生するのかが分かっていないので、直っているか分かっていません。
guest

0

そのエラーが出たタイミングで各変数の値や状態など、画面に表示させるかファイルにログとして落とすかしてみればどうでしょう。
稀に出るエラーでは、コードだけ見てもエラーの原因はわかるもんじゃありません

投稿2018/03/25 12:40

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

propg

2018/03/25 23:13

回答ありがとうございます 通常ではデバッグやログで確認するのですが、エラーが参照不足とのエラーであり、また、コンパイル時のエラーのため、どこで何を表示すべきかが分かっていない状態です。 海外のサイトで asp.netの場合に参照エラーが出る場合は、web.configに参照設定を記述する説明がありましたが、いつも出るエラーではない上、ネイティブアプリの場合の対処方法は見つけられていませ 純粋なテンプレートエンジン的な使い方をされている方はあまりいないのでしょうか?
y_waiwai

2018/03/25 23:48

そのコンパイルにかかるソースをログにでも書き出してみればどうでしょう。 そのソースが全く正当なものだ、という場合はRazorEngineのバグということになるので開発元に問い合わせるなどしてみるって話になりますね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問