Domanda

Quindi sono il rendering di una vista parziale in memoria al fine di indirizzare i dati XSL-FO in vista di un renderer PDF.

Il renderer PDF può prendere una stringa, XmlDocument o stream come input.

Ecco quello che mi piacerebbe fare: ( A cura per chiarezza )

Soluzione Tratto da: http :!!? //thriftybliss.spaces.live.com/blog/cns 58DA805F37F31F20 170.entry wa = wsignin1.0 & sa = 362.921.628

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();
        }
    }
}

Ecco cosa funziona, ma quello che preferirei non fare:

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();
}

Purtroppo la HtmlTextWriter non sembra voler scrivere al StreamWriter, o forse ho appena incasinato qualcosa in su.

Se sostituisco StreamWriter con StringWriter funziona benissimo, ma non posso usare StringWriter perché quando io chiamo .ToString () ottengo tutti i tipi di caratteri di escape che rovinare il XSL-FO e il renderer lancia un "Caratteri non ammessi "eccezione.

ho ottenuto intorno a questo con la creazione di un XmlDocument e caricare la stringa in quella, ma sembra un modo molto indiretto di fare le cose. Mi piacerebbe davvero come a poco catturare l'uscita dal HtmlTextWriter e inserirlo direttamente nel rendering. Esiste un modo per fare questo?

Grazie!

È stato utile?

Soluzione

Quando dici "HtmlTextWriter non sembra voler scrivere al StreamWriter" Vuol dire che driver.Render non può ottenere qualsiasi byte di inStream? Due possibilità mi viene in mente ...

Per prima cosa è che HtmlTextWriter non è il lavaggio del flusso dopo la scrittura fatta di, nel qual caso potrebbe essere necessario un sw.Flush() in là prima di consegnare l'inStream a driver.Render.

La seconda è che dopo aver scritto al MemoryStream, il puntatore posizione sarà alla fine del flusso, e qualsiasi tentativo di leggere da esso produrrà zero byte (poiché è alla fine).

In questo caso, l'impostazione inStream.Position a 0, o chiamando inStream.Seek(0, SeekOrigin.Begin) prima di chiamare driver.Render dovrebbe risolvere il problema.

Ho ho fatto funzionare nella seconda situazione un paio di volte prima, in modo che la mia ipotesi migliore.

Altri suggerimenti

non ho ancora testato questo a tutti. .. ma è una versione modificata di un RenderViewToString metodo che ho fatto e l'uso altrove:

    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;
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top