2010-08-30 47 views
3

因此,我在內存中渲染了一個局部視圖,以便將視圖中的XSL-FO數據引導至PDF渲染器。ASP.NET MVC:我如何將控件渲染到流?

PDF渲染器可以接受字符串,XmlDocument或Stream作爲輸入。

這裏是我想要做什麼:(編輯爲清楚起見

解決方案摘自:http://thriftybliss.spaces.live.com/blog/cns!58DA805F37F31F20!170.entry?wa=wsignin1.0&sa=362921628

var viewPage = new ViewPage(); 
var viewData = new ViewDataDictionary(model); 
viewPage.ViewData = viewData; 

var control = viewPage.LoadControl(viewName); 
viewPage.Controls.Add(control); 

using (var inStream = new MemoryStream()) 
{ 
    using (var sw = new StreamWriter(inStream)) 
    { 
     using (var tw = new HtmlTextWriter(sw)) 
     { 
      viewPage.RenderControl(tw); 
     } 
     using (var outStream = new MemoryStream()) 
     { 
      driver.Render(inStream, outStream); 
      return outStream.ToArray(); 
     } 
    } 
} 

這裏是什麼工作,但我寧願不做:

var sb = new StringBuilder(); 

using (var sw = new StringWriter(sb)) 
{ 
    using (var tw = new HtmlTextWriter(sw)) 
    { 
     vp.RenderControl(tw); 
    } 
} 

var xml = new XmlDocument(); 
xml.LoadXml(sb.ToString()); 

using (var ms = new MemoryStream()) 
{ 
    driver.Render(xml, ms); 
    return ms.ToArray(); 
} 

不幸的是,HtmlTextWriter似乎不想寫入StreamWriter,或者我只是搞砸了一些東西別的了。

如果我用StringWriter替換StreamWriter,它可以正常工作,但是我不能使用StringWriter,因爲當我調用.ToString()時,我得到了各種各樣的使XSL-FO搞亂的轉義字符,並且呈現器拋出「Illegal字符「的例外。

我通過創建一個XmlDocument並加載字符串來解決這個問題,但它似乎是一個非常迂迴的做事方式。我真的只想捕獲HtmlTextWriter的輸出並將其直接輸入到Renderer中。有沒有辦法做到這一點?

謝謝!

回答

1

當你說「的HtmlTextWriter似乎並不希望寫入StreamWriter的」那是否意味着driver.Render不能從inStream獲取任何字節?兩種可能性,我能想到的...

首先是它寫完之後,在這種情況下,你的手進入數據流來driver.Render之前,你可能需要在那裏sw.Flush()的HtmlTextWriter不刷新流。其次是在寫入MemoryStream之後,位置指針將在流的末尾,並且從它讀取的任何嘗試都將產生零字節(因爲它在末尾)。

在這種情況下,將inStream.Position設置爲0,或者在致電driver.Render之前調用inStream.Seek(0, SeekOrigin.Begin)應該修復它。

我已經遇到過幾次之前的第二種情況,所以這是我最好的猜測。

+0

謝謝!就是這樣。使用調試器進行調試我不知道爲什麼在渲染控件後instream的長度爲0。在刷新StreamWriter之後,inStream長度讀取適當的長度並在完全讀取之前將位置設置爲0。再次感謝! – 2010-08-30 17:37:04

-1

我還沒有測試過這一切。 ..但它是一個RenderViewToString method我犯和其他地方使用的修改版本:

public static Stream RenderViewToStream<T>(string viewPath, T model, ControllerContext controllerContext) 
    { 
     var ms = new MemoryStream(); 
     using (var writer = new StreamWriter(ms)) 
     { 
      var view = new WebFormView(viewPath); 
      var vdd = new ViewDataDictionary<T>(model); 
      var viewCxt = new ViewContext(controllerContext, view, vdd, new TempDataDictionary(), writer); 
      viewCxt.View.Render(viewCxt, writer); 
     } 
     return ms; 
    } 
+0

感謝您的答案,但我試圖實現我的解決方案沿着這篇文章的行:http://thriftybliss.spaces.live.com/blog/cns!58DA805F37F31F20!170.entry?wa=wsignin1。 0&sa = 362921628 我想避免使用ControllerContext,因爲我只能渲染不帶它的局部視圖。唯一的問題是字符串輸出的格式和我必須做些什麼來解決它。 – 2010-08-30 17:14:34

+0

似乎並沒有爲我工作也未經測試沒有幫助。 – Hcabnettek 2011-12-29 18:29:20

+0

「未經測試不會幫助」..對不起,Hcabnettek,讓我只是做和測試你的工作給你。 – 2011-12-30 20:53:44