2011-04-03 83 views
5

所以基本上我有一個局部視圖,可以爲我構建一個漂亮的桌子。我想每週通過電子郵件將此表發送給我的用戶。我不想再基本上覆制模板,我想將我的模型轉發給控制器,並接收相應生成的HTML作爲String在控制器或其他地方渲染部分字符串

是否可以在Controller中做到這一點,我覺得它應該是一個非常簡單的過程。

+0

增加對asp.net標籤 - 這是asp.net,對?如果提問者用他們正在使用的平臺或技術標記問題,這非常有幫助,因此回答者可以一眼就能分辨出這是否可以提供幫助。我是一個爪哇人,所以我不能,但是我不得不來到這裏,閱讀這個問題,猜測和谷歌之前,我知道我不會有任何用處! – 2011-04-03 20:43:23

+0

謝謝抱歉。沒有真正集中!是的,這是asp.net mvc – Steve 2011-04-03 20:45:57

+0

http://stackoverflow.com/questions/483091/render-a-view-as-a-string/2759898#2759898 – dotjoe 2011-04-04 23:56:46

回答

0

調查MvcMailer項目。再加上可以呈現桌子的局部視圖,您應該可以非常方便地將電子郵件與桌子放在一起。

+0

我怎麼能使用這個,如果我不打算髮送電子郵件。也許我想把控制權交給頁面? – Steve 2011-04-04 12:28:42

+0

@Steve - 我想你會使用條件邏輯來與郵件程序一起渲染或渲染一個普通的視圖。 – tvanfosson 2011-04-04 12:35:56

4

如果你搜索渲染字符串的部分視圖,你也會遇到一些很好的線索。這就是我所做的拿出了ControllerBase類以下的擴展方法:

public static string RenderPartialViewToString(this ControllerBase controller, string partialPath, ViewDataDictionary viewData = null) 
{ 
    if(string.IsNullOrEmpty(partialPath)) 
     partialPath = controller.ControllerContext.RouteData.GetRequiredString("action"); 

    using(StringWriter sw = new StringWriter()) 
    { 
     ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialPath); 

     ViewContext viewContext = new ViewContext(controller.ControllerContext, 
      viewResult.View, 
      (viewData == null) ? controller.ViewData : viewData, 
      controller.TempData, 
      sw); 

     // copy retVal state items to the html helper 
     foreach(var item in viewContext.Controller.ViewData.ModelState) 
     { 
      if(!viewContext.ViewData.ModelState.Keys.Contains(item.Key)) 
       viewContext.ViewData.ModelState.Add(item); 
     } 

     viewResult.View.Render(viewContext, sw); 

     return sw.GetStringBuilder().ToString(); 
    } 
} 

概念,遵循過程涉及使用你的應用程序中定義的ViewEngines找到它的名字的局部視圖。然後,從該部分創建一個ViewContext,並將各種模型狀態屬性複製到該部分。

代碼分配一個可以提供給ViewContext的可選ViewDataDictionary。如果您不提供ViewDataDictionary,它將抓取爲其調用的控制器定義的ViewDataDictionary。

這意味着您可以直接在您的控制器中定義ViewData值(或ViewBag屬性),然後調用擴展方法 - 它將在渲染時將這些ViewData/ViewBag屬性應用於部分;或者您可以在您的操作方法中創建一個單獨的ViewDataDictionary對象,並將其傳遞給擴展方法。第一個更快更簡單,但它會「污染」你的操作方法的ViewData,而第二個需要更長的時間來設置,但是可以讓你的部分視圖數據與操作方法的ViewData分開。

0

Render a view as a string

我使用一些簡單的像以上,但我幾乎總是創建的電子郵件獨立意見。主要是由於需要使用絕對鏈接並將CSS插入頭部。

14

要把它放到輔助文件:

public static string RenderViewToString(ControllerContext context, string viewName, object model) 
     { 
      if (string.IsNullOrEmpty(viewName)) 
       viewName = context.RouteData.GetRequiredString("action"); 

      ViewDataDictionary viewData = new ViewDataDictionary(model); 

      using (StringWriter sw = new StringWriter()) 
      { 
       ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName); 
       ViewContext viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw); 
       viewResult.View.Render(viewContext, sw); 

       return sw.GetStringBuilder().ToString(); 
      } 
     } 

再從控制器,你可以這樣調用:

var order = orderService.GetOrder(id); 

var orderPrint = MyHelper.RenderViewToString(this.ControllerContext, "_OrderView", order); 
+0

這對我有效。 +1! – 2017-09-04 23:33:00