18

新しいMVCRazorViewエンジンをメールマージテクノロジとして使用できれば面白いと思いました。それでもMVCWebサイトの一部にすることができ、スタンドアロンのコンソールアプリである必要はありません。

例:

string  myTemplate = "Hello @Name,  How are you today?";
ViewModel.Name = "Billy Boy";
string output = RazorViewEngineRender( myTemplate, ViewModel );

そうしてstring output = "Hello Billy Boy, How are you today?"

主なことは、テンプレートをビューや部分ビューではなく文字列から駆動することです。

これが可能かどうか誰かが知っていますか?

アップデート:

ベンとマットはcodeplexでプロジェクトを作成しました:http: //razorengine.codeplex.com/

4

2 に答える 2

17

警告

これは、正しく動作させる以外にテストせずに一緒にハッキングされた醜い醜いコードです。

VirtualPathProvider

サーバー上の実際のビューを扱っていないため、動的に生成されたテンプレートを取得する場所をMVCに指示するために、独自のパスプロバイダーを追加する必要があります。文字列Dictionaryをチェックして、ビューが追加されているかどうかを確認するなど、さらにテストが必要です。

public class StringPathProvider : VirtualPathProvider {
    public StringPathProvider()
        : base() {
    }

    public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) {
        return null;
    }

    public override bool FileExists(string virtualPath) {
        if (virtualPath.StartsWith("/stringviews") || virtualPath.StartsWith("~/stringviews"))
            return true;

        return base.FileExists(virtualPath);
    }

    public override VirtualFile GetFile(string virtualPath) {
        if (virtualPath.StartsWith("/stringviews") || virtualPath.StartsWith("~/stringviews"))
            return new StringVirtualFile(virtualPath);

        return base.GetFile(virtualPath);
    }

    public class StringVirtualFile : System.Web.Hosting.VirtualFile {

        string path;

        public StringVirtualFile(string path)
            : base(path) {
            //deal with this later
                this.path = path;
        }

        public override System.IO.Stream Open() {
            return new System.IO.MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(RazorViewEngineRender.strings[System.IO.Path.GetFileName(path)]));
        }
    }
}

レンダリングクラス

このクラスは、テンプレートをコンストラクターパラメーターとして受け取り、それを静的ディクショナリに追加します。このディクショナリは、VirtualPathProvider上記で読み取られます。次に、を呼び出しRender、オプションでモデルを渡すことができます。これにより、完全修飾モデルタイプがに追加@inheritsされ、ファイルの内容に追加されます。

public class RazorViewEngineRender {
    internal static Dictionary<string, string> strings { get; set; }

    string guid;

    static RazorViewEngineRender() {
        strings = new Dictionary<string, string>();
    }

    public RazorViewEngineRender(string Template) {
        guid = Guid.NewGuid().ToString() + ".cshtml";
        strings.Add(guid, Template);
    }

    public string Render() {
        return Render(null);
    }

    public string Render(object ViewModel) {
        //Register model type
        if (ViewModel == null) {
            strings[guid] = "@inherits System.Web.Mvc.WebViewPage\r\n" + strings[guid];
        } else {
            strings[guid] = "@inherits System.Web.Mvc.WebViewPage<" + ViewModel.GetType().FullName + ">\r\n" + strings[guid];
        }

        CshtmlView view = new CshtmlView("/stringviews/" + guid);

        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        System.IO.TextWriter tw = new System.IO.StringWriter(sb);

        ControllerContext controller = new ControllerContext();

        ViewDataDictionary ViewData = new ViewDataDictionary();
        ViewData.Model = ViewModel;

        view.Render(new ViewContext(controller, view, ViewData, new TempDataDictionary(), tw), tw);
        //view.ExecutePageHierarchy();

        strings.Remove(guid);

        return sb.ToString();

    }
}

Global.asax

global.asaxファイルで、以下を追加する必要があります。Application_Start

System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new Controllers.StringPathProvider());

コードを呼び出す

string Template = "Hello, @Model.Name";
Models.User user = new Models.User() { Name = "Billy Boy" };
RazorViewEngineRender view = new RazorViewEngineRender(Template);
string Results = view.Render(user); //pass in your model

ノート

これは、型指定されたモデルでのみ機能します。新しい{Name="Billy Boy"}を渡そうとしましたが、エラーが発生します。理由はわかりませんが、あまり深く調べていませんでした。

この質問をしてくれてありがとう、これは楽しかったです。

于 2010-09-28T17:02:12.210 に答える
5

Razorは、スタンドアロン操作を念頭に置いて設計されました。そのモードに関するドキュメントはまだ多くありませんが(すべてまだ開発中であるため)、AndrewNurseによるこのブログ投稿をご覧ください:http://vibrantcode.com/blog/2010/7/22/using-the- razor-parser-outside-of-aspnet.html

于 2010-09-28T05:46:37.277 に答える