Asp.Net MVC View输出为Html

2021-11-27  本文已影响0人  寻找无名的特质

某些情况下,我们需要获取MVC Razor模板生成的字符串,比如,作为发送邮件的内容等等。这时,需要获取生成的内容,下面的代码可以帮助实现这个需求:

using System.IO;
using System.Web.Mvc;

namespace RazorHelper
{
    public class RenderHelper
    {
        public static string RenderViewToString(ControllerContext context, string viewPath, object model = null, bool partial = false)
        {
            // first find the ViewEngine for this view
            ViewEngineResult viewEngineResult = null;
            if (partial)
                viewEngineResult = ViewEngines.Engines.FindPartialView(context, viewPath);
            else
                viewEngineResult = ViewEngines.Engines.FindView(context, viewPath, null);

            if (viewEngineResult == null)
                throw new FileNotFoundException("View cannot be found.");

            // get the view and attach the model to view data
            var view = viewEngineResult.View;
            context.Controller.ViewData.Model = model;

            string result = null;

            using (var sw = new StringWriter())
            {
                var ctx = new ViewContext(context, view, context.Controller.ViewData, context.Controller.TempData, sw);
                view.Render(ctx, sw);
                result = sw.ToString();
            }

            return result;
        }
    }
}

这里的关键是要有ControllerContext,这个对象是框架根据上下文生成的,也可以自己创建,下面这段代码创建了一般类型的控制器上下文:

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;
    if (System.Web.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;
}

使用时是这样的:

 var controller = ViewRenderer.CreateController<GenericController>();

从上面控制器创建的代码可以看出,关键是需要根据System.Web.HttpContext.Current 创建相关的上下文环境,也就是说,这种方式不适用于脱离Web环境的场景,比如控制台程序或者后台应用等。

上一篇下一篇

猜你喜欢

热点阅读