none
[Dúvida] - Envio de e-mail com imagem incorporada RRS feed

  • Pergunta

  • Bom dia!

    Eu estou com um problema ao enviar um e-mail com uma imagem incorporada no "body".

    Eu estou utilizando AlternateView para que a imagem apareça no corpo, só que as imagens estão indo como anexo também, com a extensão .DAT, alguém poderia me ajudar com isso?

    Eu estou utilizando Windows Forms.

    Segue abaixo meu código:

    MailMessage Message = new MailMessage();
    Message.From = new MailAddress(oCFEM.CMUSER, oCFEM.CMNAME.Trim());
    
    Message.To.Add(MA_Destinatario.Replace("|", ","));
    Message.CC.Add(MA_ComCopia.Replace("|", ","));
    Message.Bcc.Add(MA_CopiaOculta.Replace("|", ","));
    
    Message.Subject = MA_Assunto.Trim();
    Message.BodyEncoding = Encoding.Default;
    Message.Body = MA_TextoCorpo;
    Message.AlternateViews.Add(SendEmbeddedImage(Message.Body));
    
    Message.IsBodyHtml = true;
    Message.Priority = MailPriority.Normal;
    
    SmtpClient Client = new SmtpClient();
    Client = new SmtpClient(oCFEM.CMHOST, oCFEM.CMPORT);
    Client.EnableSsl = oCFEM.CMCONF;
    Client.DeliveryMethod = SmtpDeliveryMethod.Network;
    Client.UseDefaultCredentials = false;
    
    NetworkCredential Credential = new NetworkCredential(oCFEM.CMUSER, oCFEM.CMPASS);
    Client.Credentials = Credential;
    
    try
    {
         Client.Send(Message);
    }
    catch (Exception ex)
    {
         HasError = true;
         MsgError = ex.Message + "\n\n" + ex.InnerException;
    }
    finally
    {
         if (Client != null)
         {
              Client.Dispose();
              Client = null;
         }
    }

    Método SendEmbeddedImage:

    private AlternateView SendEmbeddedImage(string pHtmlBody)
    {
         string htmlBodyAux = pHtmlBody.ToLower();
         int posIni = 0;
         int posFim = 0;
         string pFileName = string.Empty;
    
         List<string> embeddedImages = new List<string>();
    
         while (htmlBodyAux.IndexOf("<img src=") != -1)
         {
              posIni = htmlBodyAux.IndexOf("<img src=\"");
              htmlBodyAux = htmlBodyAux.Substring(posIni);
    
              posFim = htmlBodyAux.IndexOf(">");
              if (posFim != -1)
              {
                   pFileName = htmlBodyAux.Substring(0, posFim);
                   pFileName = pFileName.Replace("<img src=\"", "");
                   pFileName = pFileName.Substring(0, pFileName.IndexOf("\""));
                   htmlBodyAux = htmlBodyAux.Remove(0, posFim + 1);
                   embeddedImages.Add(pFileName);
              }
          }
    
         AlternateView alternateView = AlternateView.CreateAlternateViewFromString(pHtmlBody, null, MediaTypeNames.Text.Html);
         foreach (var image in embeddedImages)
         {
              LinkedResource inline = new LinkedResource(image);
              inline.ContentId = Guid.NewGuid().ToString();
              alternateView.LinkedResources.Add(inline);
         }
    
         return alternateView;
    }

    HTML que está sendo enviado (variavel MA_TextoCorpo):

    <html>
    <head></head>
    <body style="background-color: red;">TESTE FD <br/>
    conteudo arquivo HTML.
    <br/>
    conteudo arquivo HTML 2.
    <br/>
    conteudo arquivo HTML 3.
    <br/>
    conteudo arquivo HTML 4.
    <br/>
    conteudo arquivo HTML 5.
    <br/>
    conteudo arquivo HTML 6.
    <br/>
    conteudo arquivo HTML 7.
    <br/>
    conteudo arquivo HTML 8.
    <br/>
    conteudo arquivo HTML 9.
    <br/>
    <br/>
    Imagem:
    <br/>
    <img src="C:\Users\fd\Desktop\img01.png" alt="img01">
    <br/>
    <img src="C:\Users\fd\Desktop\img02.png" alt="img02">
    <br/>
    <img src="C:\Users\fd\Desktop\img03.png" alt="img03">
    </body>
    </html>

    att.

    Felipe

    quarta-feira, 3 de maio de 2017 11:21

Respostas

  • Felipe,

    Não identifiquei no seu código onde você altera o atributo src das imagens para apontar para o ContentId definido no LinkedResource.

    Não sei se realmente é a causa do seu problema, de qualquer modo normalmente você teria que substituir o src atual por:

    <img src="cid:AQUI_VAI_CONTENT_ID_GERADO" />


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.

    quarta-feira, 3 de maio de 2017 11:45

Todas as Respostas

  • Felipe,

    Não identifiquei no seu código onde você altera o atributo src das imagens para apontar para o ContentId definido no LinkedResource.

    Não sei se realmente é a causa do seu problema, de qualquer modo normalmente você teria que substituir o src atual por:

    <img src="cid:AQUI_VAI_CONTENT_ID_GERADO" />


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.

    quarta-feira, 3 de maio de 2017 11:45
  • Puts, verdade Juliano!

    Eu não estou alterando o src pra cid, vou fazer um teste aqui, e te aviso.

    Obrigado pelo feedback.

    att.

    Felipe

    quarta-feira, 3 de maio de 2017 11:47
  • Juliano, funcionou perfeitamente!

    Segue abaixo o ajuste que foi feito no código:

    private AlternateView SendEmbeddedImage(string pHtmlBody)
    {
         string htmlBodyAux = pHtmlBody;
         int posIni = 0;
         int posFim = 0;
         string pFileName = string.Empty;
    
         Dictionary<Guid, string> embeddedImages = new Dictionary<Guid, string>();
         AlternateView alternateView = null;
    
         while (htmlBodyAux.IndexOf("<img src=") != -1)
         {
              posIni = htmlBodyAux.IndexOf("<img src=\"");
              htmlBodyAux = htmlBodyAux.Substring(posIni);
    
              posFim = htmlBodyAux.IndexOf(">");
              if (posFim != -1)
              {
                   pFileName = htmlBodyAux.Substring(0, posFim);
                   pFileName = pFileName.Replace("<img src=\"", "");
                   pFileName = pFileName.Substring(0, pFileName.IndexOf("\""));
                   htmlBodyAux = htmlBodyAux.Remove(0, posFim + 1);
    
                   //
    
                   Guid pContentId = Guid.NewGuid();
                   string htmlCid = "<img src=\"cid:" + pContentId;
                   string imgSrc = "<img src=\"" + pFileName;
    
                   pHtmlBody = pHtmlBody.Replace(imgSrc, htmlCid);
                   embeddedImages.Add(pContentId, pFileName);
              }
         }
    
         alternateView = AlternateView.CreateAlternateViewFromString(pHtmlBody, null, MediaTypeNames.Text.Html);
         foreach (var image in embeddedImages)
         {
              LinkedResource inline = new LinkedResource(image.Value);
              inline.ContentId = image.Key.ToString();
              alternateView.LinkedResources.Add(inline);
         }
    
         return alternateView;
    }

    att.

    Felipe

    quarta-feira, 3 de maio de 2017 12:31
  • Caros, boa tarde!

    Preciso reabrir esse tópico, pois estou com outro problema agora.

    O e-mail esta enviando normalmente, com as imagens corretamente.

    Porém, quando é respondido, ele volta sem as imagens, e com anexos .DAT.

    Isso é problema do programa de e-mail, ou problema no meu códio mesmo?

    att.

    Felipe

    terça-feira, 4 de julho de 2017 18:06
  • Felipe, boa tarde, voce não tem isso em um projeto pronto pra mim ver como é feito, estou precisando exatamente dessa função.
    terça-feira, 4 de julho de 2017 20:24
  • Olá Guilherme, boa tarde!

    Cara, tenho sim, eu te envio amanhã, tudo bem?

    Agora estou de saída já.

    att.

    Felipe

    terça-feira, 4 de julho de 2017 20:26
  • Caros, bom dia!

    Disponibilizei a classe que eu criei, e estou utilizando para o envio de e-mails, caso tenham interesse, segue abaixo o link:

    SendMail Class

    att.

    Felipe

    quarta-feira, 5 de julho de 2017 11:42
  • Obrigado Felipe, você não tem um form rodando com essa classe pra mim ver ele funcionando pra entender melhor?
    quarta-feira, 5 de julho de 2017 13:22
  • Bom dia, felipe022.

    Tudo bem?

    Obrigado por usar o fórum MSDN.

    Essa thread já havia sido encerrada, vi que você abriu outra questão aqui. Por questão de organização do fórum, peço que abra uma nova thread com a nova dúvida.

    Atenciosamente,


    Filipe B de Castro

    Esse conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita

    MSDN Community Support

    Por favor, lembre-se de Marcar como Resposta as postagens que resolveram o seu problema. Essa é uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.

    quarta-feira, 5 de julho de 2017 13:27
    Moderador
  • Guilherme, bom dia!

    Cara, eu até tenho, mas é muito complexo o form.

    O que você precisa fazer, basicamente, é colocar um botão na sua tela, e no evento Click dele, você chamar a classe, e o método Send.

    SendMail oSendMail = new SendMail();
    oSendMail.Send();
    
    if (oSendMail.HasError)
        MessageBox.Show("Erro ao enviar email:\n" + oSendMail.MsgError);

    Obs.: Não esqueça de preencher as variáveis com os valores corretos do seu servidor de email.

    Qualquer dúvida, estou a disposição.

    att.

    Felipe

    quarta-feira, 5 de julho de 2017 13:28
  • A sua classe já esta com aquela correção de responder a mensagem né? eu queria o form para ver a questão completa do envio de e-mail, aonde anexa imagem etc, mas tudo bem, agradeço pela atenção.
    quarta-feira, 5 de julho de 2017 17:50