Avatar billede jpi Mester
16. oktober 2006 - 22:32 Der er 29 kommentarer og
2 løsninger

Streame genereret pdf-fil til browser + mail

Jeg har hentet iTextSharp (http://sourceforge.net/projects/itextsharp/) og vil bruge det til at generere PDF-filer via en ASP.NET applikation. (se evt. http://www.eksperten.dk/spm/737186
Dog skal filerne ikke lægges på serveren, men streames direkte til browseren + streames til en vedhæftet fil i en mail.

Det med at der genereres en fil på serveres, som man så linker til og vehæfter en mail er jeg ikke interesseret i.

Er der nogen der kan hjælpe ?
Avatar billede dj_uncas Nybegynder
16. oktober 2006 - 23:17 #1
Den nemmeste måde at komme over hegnet her må være at:

1. Oprette filen på serveren
2. Sende den til brugeren + mail
3. Slette filen igen med det samme
Avatar billede dj_uncas Nybegynder
16. oktober 2006 - 23:18 #2
Alternativt se her:
http://itextsharp.sourceforge.net/tutorial/ch01.html

I "Step 2" står der at du kan sende dokumentet til hvilken som helst Stream. Så kan du jo bare sende det til output streamen på ASP.NET siden og sætte ContentType til pdf.
Avatar billede dj_uncas Nybegynder
16. oktober 2006 - 23:20 #3
I denne stil:

protected void Page_Load()
{
    Document document = new Document();
    PdfWriter.getInstance( document, Response.OutputStream );
    document.Open();
    document.Add( new Paragraph("Hello World" ) );
    document.Close();

    Response.ContentType = "application/pdf";
}
Avatar billede arne_v Ekspert
17. oktober 2006 - 04:28 #4
måske skulle ContentType sættes først måske suppleres med en Content-Disposition header
Avatar billede dj_uncas Nybegynder
17. oktober 2006 - 13:07 #5
Det er vel sådan set ligegyldigt hvornår man sætter ContentType, hvis mit eksempel bliver skrevet i Page_Load?! Det er først senere (omkring Render) at output streamen bliver udskrevet.

Content-Disposition er også fornuftigt at have med - det vil jeg give dig ret i! Jeg havde bare glemt den :-(
Avatar billede jpi Mester
17. oktober 2006 - 13:54 #6
Er der nogen der hurtigt kan oversætte det til VB ?
Avatar billede dj_uncas Nybegynder
17. oktober 2006 - 22:29 #7
Der skal vi formentlig have arne_v på banen.. Han er noget sejere til VB end jeg er.
Avatar billede arne_v Ekspert
18. oktober 2006 - 01:25 #8
utestet:

Protected Sub Page_Load()
    Dim document As Document = New Document()
    PdfWriter.getInstance( document, Response.OutputStream )
    document.Open()
    document.Add( New Paragraph("Hello World" ) )
    document.Close()

    Response.ContentType = "application/pdf"
End Sub
Avatar billede arne_v Ekspert
18. oktober 2006 - 01:27 #9
dj_uncas>

Hvis den bufferer alt - får man så ikke problemer med store filer ?
Avatar billede dj_uncas Nybegynder
18. oktober 2006 - 13:34 #10
Du får vist ca. samme problemer som hvis du sender filen direkte til brugeren (uden om .NET). Der sker jo ikke andet en at output streamen bliver kørt gennem .NET ...

Jeg har kørt ret store filer (installationspakker) ud til brugere over web på denne måde, uden de store problemer. Og .zip pakkerne blev endda hentet fra Sharepoint!
Avatar billede arne_v Ekspert
19. oktober 2006 - 02:18 #11
hvis man downloader en stor fil fra en web server, så sender den skam første del af filen
inden den læser sidste del af filen

jeg ville have troet at ASP.NET gjorde det samme

men det kræver at content type sættes først, da den skal sendes til browser
inden første byte

hvis content type kan sættes til sidst så betyder det at alt der skal sendes
til browser bufferes i memory

hvis man vil streame en 650 MB ISO, så er det jo lidt memort forbrugende ...
Avatar billede dj_uncas Nybegynder
19. oktober 2006 - 10:49 #12
Det har du nok ret i. Man skal nok sætte ContentType først før serveren overhovedet kan sende filen ud før den er færdig bufferet.
Avatar billede jpi Mester
19. oktober 2006 - 18:03 #13
Det virker perfekt.
Er der mulighed for at kunne definere navnet på den fil der streames til brugeren ?

Så mangler der det med mailen. Jeg er ikke interesseret i løsningen med at lave en fil som så skal slettes. Jeg vil gerne kunne streame direkte til en mail som så sendes.
Avatar billede arne_v Ekspert
19. oktober 2006 - 18:56 #14
det kan du netop angive i Content-Disposition
Avatar billede arne_v Ekspert
19. oktober 2006 - 19:01 #15
MailMessage.Attachments.Add kan saa vidt jeg kan laese udfra docs tage en stream
Avatar billede jpi Mester
19. oktober 2006 - 20:44 #16
Beklager meget, men jeg er ikke så skarp til det.
Det med filnavnet, hvordan ser kodelinien ud til det ?

Og det med stream kan jeg ikke lige få til at funke. Hvordan skal det sættes sammen ?
Jeg har fået den til at sende en mail med vedhæftet fil:

        Dim Msg As New MailMessage()
        Dim MailObj As New SmtpClient("mail.test.dk")

        Msg.From = New MailAddress("mail@test.dk", "Test")
        Msg.To.Add(New MailAddress("mail@test.dk", "test1"))
        Msg.IsBodyHtml = "False"
        Msg.Body = "Tekst i mail"
        Msg.Subject = "Emnefelt"
        Dim d As New Attachment("temp.pdf")
        Msg.Attachments.Add(d)
        MailObj.Send(Msg)

Hvordan får man stream'en ned i mailen og evt. med et defineret filnavn ?
Avatar billede jpi Mester
19. oktober 2006 - 21:58 #17
Har fået det med filnavnet til at virke.

Response.AddHeader "Content-Disposition", "inline; filename=filnavn.pdf"
for at få browseren til at downloade filen skrives:
Response.AddHeader "Content-Disposition", "attachment; filename=filnavn.pdf"
Avatar billede dj_uncas Nybegynder
19. oktober 2006 - 22:02 #18
Du skal såmænd bare proppe din stream direkte ned som attachment:

(Forudsat du først har lavet alt det smart foreslået ovenfor)

Attachment att = new Attachment( Response.OutputStream, "application/pdf" );
Msg.Attachments.Add( att );

osv.
Avatar billede jpi Mester
19. oktober 2006 - 22:23 #19
Dim document = New Document()
        PdfWriter.GetInstance(document, Response.OutputStream)
        document.Open()
        document.Add(New Paragraph("Hello World i mail"))
        document.Close()

        Dim Msg As New MailMessage()
        Dim MailObj As New SmtpClient("mail.test.dk")

        Msg.From = New MailAddress("mail@test.dk", "Test")
        Msg.To.Add(New MailAddress("webmaster@test.dk", "test1"))
        Msg.IsBodyHtml = "False"
        Msg.Body = "Tekst i mail"
        Msg.Subject = "Emnefelt"
        Dim d = New Attachment(Response.OutputStream, "application/pdf")

        Msg.Attachments.Add(d)
        MailObj.Send(Msg)

Kan ikke lige se hvilket der er galt. Det virker ikke, den skriver at "Specified method is not supported"
Avatar billede jpi Mester
19. oktober 2006 - 22:52 #20
Her rettet en linie til:
Dim d = New Attachment(Response.OutputStream, "ttt.pdf", System.Net.Mime.MediaTypeNames.Application.Pdf)
Det går galt i selve Msg.Attachment.Add(d). HVis den remmes ud er der ingen problemer (men heller ingen attachment ;-)
Avatar billede jpi Mester
24. oktober 2006 - 22:50 #21
Således ser koden ud:

        Dim document = New Document()
        Dim m As New System.IO.MemoryStream()
        PdfWriter.GetInstance(document, Response.OutputStream)
        document.Open()
        document.Add(New Paragraph("Hello World i mail"))
        document.Close()

        Dim Msg As New MailMessage()
        Dim MailObj As New SmtpClient("mail.mailserver.dk")

        Msg.From = New MailAddress("mail@test.dk", "Test")
        Msg.To.Add(New MailAddress("webmaster@test.dk", "test1"))
        Msg.IsBodyHtml = "False"
        Msg.Body = "this is the Email body"
        Msg.Subject = "This is the Subject"
        Dim d = New Attachment(Response.OutputStream, "ttt.pdf", System.Net.Mime.MediaTypeNames.Application.Pdf)

        Msg.Attachments.Add(d)
        MailObj.Send(Msg)

Og fejlkoden når man prøver det ser således ud:

Server Error in '/' Application.
--------------------------------------------------------------------------------

Specified method is not supported.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NotSupportedException: Specified method is not supported.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Stack Trace:


[NotSupportedException: Specified method is not supported.]
  System.Web.HttpResponseStream.Read(Byte[] buffer, Int32 offset, Int32 count) +28
  System.Net.Mime.MimePart.Send(BaseWriter writer) +113
  System.Net.Mime.MimeMultiPart.Send(BaseWriter writer) +286
  System.Net.Mail.Message.Send(BaseWriter writer, Boolean sendEnvelope) +96
  System.Net.Mail.SmtpClient.Send(MailMessage message) +1736

[SmtpException: Failure sending mail.]
  System.Net.Mail.SmtpClient.Send(MailMessage message) +2074
  Default2.Button1_Click(Object sender, EventArgs e) +574
  System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105
  System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +107
  System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
  System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
  System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
  System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5102


Nogen ideer til hvad der kan være galt, og evt. hvordan det kan fås til at virker ?
Avatar billede arne_v Ekspert
25. oktober 2006 - 04:13 #22
Du kan ikke læse fra Response.Output !
Avatar billede arne_v Ekspert
25. oktober 2006 - 04:15 #23
Gem dit PDF til en MemoryStream, hiv et byte array ud af den, kopier det byte array
til Response.Output, wrap det byte array i en ny MemoryStream og angive den til
Attachment,
Avatar billede jpi Mester
25. oktober 2006 - 08:23 #24
OK, det lyder rigtígt nok. Det er bare lidt for langhåret til mig...
Kan jeg evt. få det i kode (helst i VB) ?
Avatar billede jpi Mester
27. oktober 2006 - 20:15 #25
Ingen der kan lave det til kode ?
Avatar billede arne_v Ekspert
29. oktober 2006 - 04:09 #26
...
Dim ms1 As MemoryStream = New MemoryStream()
...
PdfWriter.GetInstance(document, ms1)
...
Dim b() As Byte = ms1.ToArray()
Response.BinaryWrite(b)
...
Dim ms2 As MemoryStream = New MemoryStream(b)
Dim d As Attachment = New Attachment(ms2, "ttt.pdf", System.Net.Mime.MediaTypeNames.Application.Pdf)
...
Avatar billede jpi Mester
02. december 2006 - 00:14 #27
Havde ikke fået lukket dette spm. Det virker bare perfekt, så smid et svar
Avatar billede arne_v Ekspert
02. december 2006 - 02:25 #28
moi ?
Avatar billede dj_uncas Nybegynder
02. december 2006 - 12:40 #29
eller mig ??
Avatar billede jpi Mester
02. december 2006 - 12:47 #30
Har delt point lidt mellem jer. I havde begge fat i det rigtige, dog var arne_v mere brugbart med VB.

Håber det er OK for jer, ellers må jeg lave et ekstra spm.

tak for hjælpen
Avatar billede dj_uncas Nybegynder
02. december 2006 - 14:34 #31
helt fint ;-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester