ASP.NET MVC: Как я могу сделать контроль на поток?
-
25-09-2019 - |
Вопрос
Итак, я делаю частичный вид в памяти, чтобы направить данные XSL-FO в представлении в PDF Renderer.
PDF Renderer может взять строку, XMLDocument или Stream в качестве ввода.
Вот что я хотел бы сделать :(Отредактировано для ясности)
Решение, взятое из: http://thriftybliss.spaces.live.com/blog/cns!58da805f37f31f20 !170.entry?wa=wsign1.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, или, возможно, я просто запутал что-то еще.
Если я заменил StreamWriter со StringWriter, он работает нормально, но я не могу использовать StringWriter, потому что когда я звоню .toString () Я получаю все виды эвакуальных символов, которые запутают XSL-Fo, и рендерер бросает исключение «незаконные символы».
Я перебирал это, создав XMLDocument и загружаю струну в это, но кажется, что очень круглое способом делать вещи. Я действительно просто хотел бы просто захватить вывод из HTMLTextWriter и кормить его непосредственно в рендерер. Есть какой-либо способ сделать это?
Спасибо!
Решение
Когда вы говорите, что «HTMLTextWriter, похоже, не хочет писать на Streamwriter», это означает, что driver.Render
Не могу получить байты из Instruam? Две возможности я могу думать о ...
Во-первых, в том, что HTMLTextWriter не промывает поток после того, как он сделан написание, в этом случае вам может понадобиться sw.Flush()
там до того, как вы передаете инструмента driver.Render
.
Во-вторых, после записи в MemoryStream указатель местоположения будет в конце потока, а любые попытки чтения из него принесут нулевые байты (поскольку он находится в конце).
В этом случае установка inStream.Position
до 0 или звонить inStream.Seek(0, SeekOrigin.Begin)
до звонка driver.Render
должен исправить это.
Я столкнулся во вторую ситуацию несколько раз раньше, так что это мое лучшее предположение.
Другие советы
Я не проверил это вообще... но это модифицированная версия Метод RenderviewToString Что я сделал и использую в другом месте:
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;
}