ASP.NET MVC中的Server.Execute()

时间:2009-10-12 19:59:35

标签: asp.net-mvc

ASP.NET MVC中是否有与Server.Execute()等效的内容?

显然只适用于传统的webforms .aspx页面。

更新 我需要从同一控制器中的不同操作中获取呈现的HTML以生成PDF。也许有一种方法可以在不将html输出到响应流的情况下执行View?

4 个答案:

答案 0 :(得分:2)

看看这个解决方案:

Render a view as a string

我用它来生成局部视图并且它有效。你必须切换到局部,但不应该是问题。

修改

我做了一些修正,使用了反射器并使用了之前问题的解决方案。这段代码看起来更好。视图渲染引擎与HttpContext.Current紧密相关,因此我们必须做一些黑客攻击:

    /// <summary>Renders a view to string.</summary>
    public static string RenderViewToString(this Controller controller,
                                            string viewName, object viewData)
    {
        //Getting current response
        var response = HttpContext.Current.Response;
        //Flushing
        response.Flush();

        //Finding rendered view
        var view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName).View;
        //Creating view context
        var viewContext = new ViewContext(controller.ControllerContext, view,
                                          controller.ViewData, controller.TempData);

        //Since RenderView goes straight to HttpContext.Current, we have to filter and cut out our view
        var oldFilter = response.Filter;
        Stream filter = new MemoryStream(); ;
        try
        {
            response.Filter = filter;
            viewContext.View.Render(viewContext, null);
            response.Flush();
            filter.Position = 0;
            var reader = new StreamReader(filter, response.ContentEncoding);
            return reader.ReadToEnd();
        }
        finally
        {
            filter.Dispose();
            response.Filter = oldFilter;
        } 
    }

它应该很容易转换为允许渲染View(将ViewEngines.Engines.FindPartialView更改为ViewEngines.Engines.FindView)。我没有看到更好的解决方案。

答案 1 :(得分:0)

MVC中的Server.Execute等效于简单地实例化所需的控制器并执行操作方法。

public ActionResult EntryAction()
{
    ProductController pc = new ProductController();

    return pc.Index();
}

当然,如果所需的操作位于同一个控制器上,您可以跳过第一步。

答案 2 :(得分:0)

非常感谢您的RenderViewToString代码段。我必须进行一些更改,然后将其集成到我们的基本控制器中,但它的效果非常好。

    /// <summary>Renders a view to string.</summary>
    public string RenderViewToString(ViewResult viewResult)
    {
        //Getting current response
        //var response = HttpContext.Current.Response;
        var response = Response;
        //Flushing
        response.Flush();

        //Finding rendered view
        var view = ViewEngines.Engines.FindView(ControllerContext, viewResult.ViewName, viewResult.MasterName).View;

        //Creating view context
        var viewContext = new ViewContext(ControllerContext, view,
                                          ViewData, TempData);

        //Since RenderView goes straight to HttpContext.Current, we have to filter and cut out our view
        var oldFilter = response.Filter;
        Stream filter = new MemoryStream();
        try
        {
            response.Filter = filter;
            viewContext.View.Render(viewContext, null);
            response.Flush();
            filter.Position = 0;
            var reader = new StreamReader(filter, response.ContentEncoding);
            return reader.ReadToEnd();
        }
        finally
        {
            filter.Dispose();
            response.Filter = oldFilter;
        }
    }

答案 3 :(得分:0)

我已经以MVC的方式实现了这一点,它适用于所有结果类型。包括文件下载。

我创建了一个自定义ActionResult ExecuteUrlResult ,并在BaseController中创建了两个 Helper方法

ExecuteUrlResult

public class ExecuteUrlResult : ActionResult
{
    public string Url { get; protected set; }
    public bool PreserveForm { get; protected set; }

    public ExecuteUrlResult(string url)
    {
        this.Url = url;
    }
    public ExecuteUrlResult(string url, bool preserveForm)
    {
        this.Url = url;
        this.PreserveForm = preserveForm;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Server.Execute(this.Url, this.PreserveForm);
    }
}

帮助方法

    protected internal ExecuteUrlResult ExecuteUrl(string url)
    {
        return new ExecuteUrlResult(url);
    }
    protected internal ExecuteUrlResult ExecuteUrl(string url, bool preserveForm)
    {
        return new ExecuteUrlResult(url, preserveForm);
    }