簡體   English   中英

通過調用控制器的動作將部分視圖轉換為字符串

[英]Transform partial view into string with calling controller's action

我有MVC控制器,其操作返回部分視圖。 動作包含大量邏輯,並通過ViewBag對象在視圖中發送數據。

我需要將此操作的結果呈現為字符串,然后作為電子郵件發送。 我發現的所有解決方案都可以渲染視圖,而無需執行任何操作。

是否可以在我的代碼中的某個地方初始化控制器,調用動作方法並將ActionResult(即局部視圖)轉換為字符串?

謝謝

我做的。 帶着很多痛苦。

首先,我們需要在沒有上下文的情況下初始化控制器。 為此,我使用了Rick Strahl的名為CreateController的方法

 public static T CreateController<T>(RouteData routeData = null)
        where T : Controller, new()
    {
        // create a disconnected controller instance
        T controller = new T();

        // get context wrapper from HttpContext if available
        HttpContextBase wrapper = null;
        if (HttpContext.Current != null)
            wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
        else
            throw new InvalidOperationException(
                "Can't create Controller Context if no active HttpContext instance is available.");

        if (routeData == null)
            routeData = new RouteData();

        // add the controller routing if not existing
        if (!routeData.Values.ContainsKey("controller") && !routeData.Values.ContainsKey("Controller"))
            routeData.Values.Add("controller", controller.GetType().Name
                                                        .ToLower()
                                                        .Replace("controller", ""));

        controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
        return controller;
    }

來源: http//weblog.west-wind.com/posts/2013/Jul/15/Rendering-ASPNET-MVC-Razor-Views-outside-of-MVC-revisited

但是,如果在HttpContext時調用此方法,它將拋出異常。 為了防止我使用以下代碼初始化虛假上下文: https : //stackoverflow.com/a/19709225/1850880

然后,我初始化控制器並調用動作。 該操作的結果包含viewData以及從操作傳遞的所有數據。 我們可以通過反射來獲得它(就像忍者一樣)。 然后,我們可以使用傳遞的模型將視圖呈現為字符串。

        var controller = CreateController<ControllerName>();
        var result = controller.ActionName(param1, param2);
        object viewData = result.GetType().GetProperty("ViewData").GetValue(result);
        object values = viewData.GetType().GetProperty("Values").GetValue(viewData);
        var str = ec.RenderRazorViewToString("ViewName", values);
        return str;

此方法將視圖渲染為字符串:

 public static string RenderRazorViewToString(this Controller controller, string viewName, object model)
    {
        controller.ViewData.Model = model;
        controller.ViewBag.Model = model;
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
            var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(controller.ControllerContext, viewResult.View);
            return sw.GetStringBuilder().ToString();
        }
    }

看起來這不是最好的方法,但是它可以工作。 因此,如果您有任何想法,請務必寫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM