2012-03-08 98 views
3

我有一個帶有outputCache的控制器的局部視圖,因爲我需要緩存這個元素。有沒有辦法在控制器中獲取PartialView HTML內容?

然後我需要在每個頁面中渲染這個PartialView,但首先我需要做一些字符串替換。

所以我的問題是,我如何在控制器中獲得部分視圖,以便在操作內容並在將其返回給視圖之前進行一些字符串替換?

感謝

回答

2

不,不要這樣做。你的控制器不應該渲染你的視圖,這是模板引擎的工作。

將「替換」值作爲模型傳遞給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> 
+0

是的,這是可行的,但在我的情況下,我需要緩存PartialView作爲從另一個網站加載的外部組件。我看不到我怎麼能保持它緩存,否則... – user441365 2012-03-08 16:07:43

+0

你可以通過各種參數緩存。請參閱[VaryBy屬性](http://msdn.microsoft.com/zh-cn/library/system.web.mvc.outputcacheattribute.aspx)。 – jrummell 2012-03-08 16:15:10

+0

啊!這可能會有所幫助 - 我會給它一個去看 – user441365 2012-03-08 16:28:27

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 S IN以便手動渲染器的背景之外的諧音或意見的情況。

+0

謝謝 - 你會把這些方法放在哪裏? – user441365 2012-03-08 16:13:42

+1

就像我提到的,在基本控制器 – bevacqua 2012-03-08 16:16:19

0

只是想分享一個修改@尼科的解決方案,如果你想從你的控制器動作使用ViewBag數據然後更改RenderViewToString如下,我用控制器.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; 
} 
相關問題