2

オブジェクトを取得して適切なテキストをレンダリングするため に作成しようと考えたCustomerオブジェクトに固有のhtml(電子メールメッセージの本文用)を生成する必要があります。
ViewCustomer

ビューを呼び出して、コントローラーアクションに関連付けずにレンダリングされた出力を取得する方法はありますか?

理想的にはpseydocodeで私はこのようなことをします

customer = new Customer();
view = new GetCustomerEmailBodyView(customer);
string htmlBody = view.SomeFunctionToRenderViewAndGetOutput()

プロパティを公開するActionResultの代わりにStringResult( ViewResultから継承)を返すアクションを持つビューのHTMLを取得するための解決策を見つけましたHtml
ただし、それを呼び出すにはまだカスタムアクションを作成する必要があり、それがControllerContextに依存しているため、テストが困難であるという事実は気に入らない。

私がMVCプリンシパルに対して要求しているものはありますか?このシナリオでは、コードをどのように構成する必要がありますか?

4

2 に答える 2

3

オリジナルコードはこちらから

protected string RenderPartialViewToString(string viewName, object model) {
    if (string.IsNullOrEmpty(viewName))
        viewName = ControllerContext.RouteData.GetRequiredString("action");
    ViewData.Model = model;
    using (StringWriter sw = new StringWriter()) {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
        ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}
于 2010-10-29T22:25:16.773 に答える
1

あるプログラムがコントローラーコンテキストにまったくいなくてもビューを利用できるようにしたい、または他のプログラムを呼び出さずにコントローラー内からビューを文字列にレンダリングできるようにしたいということですか?コントローラ?

前者の場合、私はあまり役に立ちませんが、後者の場合、他のすべてのコントローラーで継承する基本コントローラータイプにこのメソッドがあります。

    /// <summary>
    /// Generates a string based on the given PartialViewResult.
    /// </summary>
    /// <param name="partialViewResult"></param>
    /// <returns></returns>
    protected internal string RenderPartialViewToString(ViewResultBase partialViewResult)
    {
        Require.ThatArgument(partialViewResult != null);
        var context = ControllerContext;
        Require.That(context != null);
        using (var sw = new StringWriter())
        {
            if (string.IsNullOrEmpty(partialViewResult.ViewName))
            {
                partialViewResult.ViewName = context.RouteData.GetRequiredString("action");
            }
            ViewEngineResult result;
            if (partialViewResult.View == null)
            {
                result = partialViewResult.ViewEngineCollection.FindPartialView(context, partialViewResult.ViewName);
                Require.That(result.View != null,
                             () => new InvalidOperationException(
                                       "Unable to find view. Searched in: " +
                                       string.Join(",", result.SearchedLocations)));
                partialViewResult.View = result.View;
            }

            var view = partialViewResult.View;
            var viewContext = new ViewContext(context, view, partialViewResult.ViewData,
                                              partialViewResult.TempData, sw);
            view.Render(viewContext, sw);
            return sw.ToString();
        }
    }

使用法:

public ActionResult MyAction(...) 
{
    var myModel = GetMyModel(...);
    string viewString = RenderPartialViewToString(PartialView("MyView", myModel));
    // do something with the string
    return someAction;
}

実際には、これをイベントベースのAJAXモデルで使用します。このモデルでは、ほとんどのアクションが実際にはAJAXでエンコードされたクライアント側イベントのリストを返します。これらのクライアント側イベントの一部は、特定のDOM要素を文字列で更新する場合があります。この部分ビューをレンダリングすることによって生成されます。

于 2010-10-29T22:21:08.990 に答える