有没有办法在控制器中获取部分视图HTML内容?

时间:2012-03-08 15:47:09

标签: asp.net-mvc asp.net-mvc-3

我有一个带有outputCache的控制器的局部视图,因为我需要缓存这个元素。

然后我需要在每个页面中渲染这个PartialView,但首先我需要做一些字符串替换。

所以我的问题是,如何在控制器中获得部分视图,以便我可以操作内容并在将其返回到View之前进行一些字符串替换?

由于

3 个答案:

答案 0 :(得分:8)

我在自定义Controller基础上使用这些方法。

    public string RenderPartialToString(string partialViewName, object model)
    {
        InvalidateControllerContext();
        IView view = ViewEngines.Engines.FindPartialView(ControllerContext, partialViewName).View;
        string result = RenderViewToString(view, model);
        return result;
    }

    public string RenderViewToString(string viewName, object model)
    {
        InvalidateControllerContext();
        IView view = ViewEngines.Engines.FindView(ControllerContext, viewName, null).View;
        string result = RenderViewToString(view, model);
        return result;
    }

    public string RenderViewToString(IView view, object model)
    {
        InvalidateControllerContext();
        string result = null;
        if (view != null)
        {
            StringBuilder sb = new StringBuilder();
            using (StringWriter writer = new StringWriter(sb))
            {
                ViewContext viewContext = new ViewContext(ControllerContext, view, new ViewDataDictionary(model), new TempDataDictionary(), writer);
                view.Render(viewContext, writer);
                writer.Flush();
            }
            result = sb.ToString();
        }
        return result;
    }

    private void InvalidateControllerContext()
    {
        if (ControllerContext == null)
        {
            ControllerContext context = new ControllerContext(System.Web.HttpContext.Current.Request.RequestContext, this);
            ControllerContext = context;
        }
    }

InvalidateControllerContext方法适用于需要手动实例Controller的场景,以便在控制器的上下文之外呈现部分或视图。

答案 1 :(得分:2)

不,不要这样做。你的控制器不应该渲染你的View,这是模板引擎的工作。

将“替换”值作为模型传递给PartialView。

public ActionResult SomeAction()
{
  SomeModelmodel = new SomeModel(); // your model
  return PartialView(model); // partial view with your model
}

部分视图:

@model SomeModel

<div>Replace your values with @Model.Value instead of String.Replace().</div>

答案 2 :(得分:0)

只想分享对@Nico解决方案的修改,如果您想使用控制器操作中的ViewBag数据然后按如下所示更改RenderViewToString,我使用controller.TempData而不是new TempDataDictionary()

public string RenderViewToString( IView view, object model)
{
    InvalidateControllerContext();
    string result = null;
    if (view != null)
    {
        StringBuilder sb = new StringBuilder();
        using (StringWriter writer = new StringWriter(sb))
        {
            // use TempData from controller
            ViewContext viewContext = new ViewContext(ControllerContext, view, 
                new ViewDataDictionary(model), this.TempData, writer);
            view.Render(viewContext, writer);
            writer.Flush();
        }
        result = sb.ToString();
    }
    return result;
}