0 votes
by (260 points)

Good morning,

I'm encountering an exception while trying to load the stream of certain EML files using the Rebex library. This issue only occurs with a limited number of files. Below is the code I'm using for loading the stream:

public static void TestRebex(string folderPath) {
    List<MailMessage> emails = new List<MailMessage>();

    string[] emlFiles = Directory.GetFiles(folderPath, "*.eml");

    foreach (string filePath in emlFiles)
    {
        using (FileStream fs = new FileStream(filePath, FileMode.Open))
        {
            MailMessage email = new MailMessage();
            email.Load(fs);
            emails.Add(email);
        }
    }
}

Exception StackTrace:

   at kdtpl.zuplm.rnrto(String p0)
   at Rebex.Mime.Headers.MimeParameterList.zkrdk(ctygm p0)
   at Rebex.Mime.Headers.ContentType.bpezc(ctygm p0)
   at Rebex.Mime.MimeHeader.fdqhx(String p0, String p1)
   at Rebex.Mime.MimeHeader.get_Value()
   at Rebex.Mime.MimeEntity.jqwiv(Encoding p0, Encoding p1)
   at kdtpl.kmpif.tzdze(Byte[] p0, Int32 p1, Int32 p2)
   at kdtpl.kmpif.uaeta(Byte[] p0, Int32 p1, Int32 p2, Boolean p3)
   at kdtpl.khhpg.nmpsc(Boolean p0)
   at kdtpl.khhpg.Write(Byte[] buffer, Int32 index, Int32 count)
   at Rebex.Mime.MimeEntity.qbeow(Stream p0, Boolean p1)
   at Rebex.Mail.MailMessage.Load(Stream input)
   at xxxxxxxxxxxx.TestRebex() in xxxxxxxxxxxxxri.cs:line 1595

I'd like to emphasize that, unfortunately, I can't share the EML files causing the exception with you. However, I was wondering if you could provide some suggestions on what I could check or which direction I could take to resolve this issue.

Thank you for your support.

Best regards,
Francesco

1 Answer

0 votes
by (147k points)
selected by
 
Best answer

It looks like you already reported this issue last year, and I posted a link for a hotfix. Please give it a try and let us know whether it resolves the issue.

by (260 points)
Thank you very much, the new version of Rebex works correctly.
by (260 points)
I've encountered a new issue with the same code, only with a specific .eml file. When I try to load this .eml, the resulting MailMessage object has an empty Attachments collection (despite the .eml file containing multiple attachments).
Unfortunately, I cannot share the EML file. Can you provide me with some tips to understand what is preventing the reading of the attachments?
by (147k points)
This is usually due to erroneous message structure such as wrongly-encoded MIME parameters in message headers. Would it be possible to open the message in a text editor such as Notepad, locate all occurrences of Content-Type header, and mail them to us for analysis?
by (260 points)
Thank you very much for the response, below you will find all the occurrences of Content-Type that I found in the EML file:

Content-Type: multipart/related;
Content-Type: multipart/alternative;
Content-Type: text/html; charset=Cp1252
Content-Type: text/plain; charset=Cp1252
Content-Type: application/pdf;
Content-Type: application/pdf; name=allegato_A.pdf
Content-Type: application/pdf; name=allegato_B.pdf
Content-Type: application/pdf; name=allegato_C.pdf
Content-Type: application/xml; name=segnatura.xml
by (147k points)
Some of these Content-type headers seem incomplete - those that end with ";" post likely consist of multiple lines. Would it be possible to post those additional lines as well?
by (260 points)
Content-Type: multipart/related;
    boundary="----=_Part_45163_1955009225.1654527913793"
   
Content-Type: multipart/alternative;
    boundary="----=_Part_45162_777609370.1654527913793"

Content-Type: text/html; charset=Cp1252
Content-Transfer-Encoding: quoted-printable

Content-Type: text/plain; charset=Cp1252
Content-Transfer-Encoding: quoted-printable

Content-Type: application/pdf;
    name=Letterarichiestaapprovazionedecreto-cc.pdf
Content-Transfer-Encoding: base64
Content-ID: <0c57f724-61a6-45d1-bb9e-e8253b27539c>
Content-Disposition: attachment;
    filename=Letterarichiestaapprovazionedecreto-cc.pdf

Content-Type: application/pdf; name=allegato_A.pdf
Content-Transfer-Encoding: base64
Content-ID: <2dbc13cc-5d2d-4b9c-90b1-282ca3663323>
Content-Disposition: attachment; filename=allegato_A.pdf

Content-Type: application/pdf; name=allegato_B.pdf
Content-Transfer-Encoding: base64
Content-ID: <9a4f04ec-1c50-40a5-b4e2-c1e17dc59940>
Content-Disposition: attachment; filename=allegato_B.pdf

Content-Type: application/pdf; name=allegato_C.pdf
Content-Transfer-Encoding: base64
Content-ID: <bae9b284-e72d-420b-a56b-0d0a8889b2db>
Content-Disposition: attachment; filename=allegato_C.pdf

Content-Type: application/xml; name=segnatura.xml
Content-Transfer-Encoding: base64
Content-ID: <14f4cd6b-ea4d-4fd6-ae96-5b945624215c>
Content-Disposition: attachment; filename=segnatura.xml
by (147k points)
Thanks! It looks like the problem is caused by the "multipart/related" Content-type header which is used by the top-level entity instead of "multipart/mixed". This makes the parser treat the attachments as resources, which means it adds them to MailMessage.Resources instead of MailMessage.Attachments collection. Please check the Resources collection - the attachments should be there instead.
by (260 points)
Thank you for your response. I've confirmed that the attachments are indeed properly placed within the Resources collection. However, I have some questions regarding the contents of this collection. What exactly gets placed inside Resources? If I were to create a method that concatenates the two collections (Attachments and Resources), would I risk making an error?
by (147k points)
The Resources collection is supposed to contain resources referenced by the HTML body, such as embedded images. In this case, a workaround that would work is to iterate through the Resources collection, and move "resources" that have a file name and whose disposition is "filename" to the Attachments collection:

    var message = new MailMessage();
    message.Load(...);

    for (int i = 0; i < message.Resources.Count; i++)
    {
        var res = message.Resources[i];
        var cd = res.ContentDisposition;
        if (cd != null && cd.FileName != null && cd.Disposition == "attachment")
        {
            // convert the resource to attachment
            var att = new Attachment(res.GetContentStream(), res.FileName, res.MediaType);
            message.Attachments.Add(att);

            // remove it from resources
            message.Resources.RemoveAt(i--);
        }
    }
by (260 points)
Thank you very much, the solution you proposed works perfectly.
...