본문 바로가기
프로그래밍/C#.NET

[1-1]C# Email 보내기(blob 첨부파일 포함) 정리(C# email attachment blob)

by Daily Investing 2012. 10. 24.
반응형

[1-1]window service를 이용해서 C# Email 보내기(blob 첨부파일 포함)

* issue

1. window service 를 이용하여 1분 단위로 배치를 돌아서 메일 테이블에 있는 미전송 메일 데이터를 전송한
    다. (단, 첨부파일이 있으며, blob 형식으로 첨부파일을 관리한다.)

* 처리방법 

1. window service 는 디버깅 하기가 애매하므로 C# winform 으로 먼저 기능을 개발(디버깅 용이) 

2. blob 형식의 데이터를 email 에 attachment 로 추가하는 기능을 개발한다.
(첨부파일 size 대로 첨부가 되는지 중요. encoding 또는 byte array 의 size 가 정확한지 확인해야 함)

3. blob 형식으로 oracle table 에 데이터를 입력하는 기능을 개발한다. (마이플랫폼 UI 사용)

4. window service 에 소스 이관 및 window service 실행 및 테스트

* 개발(처리)순서 및 참고 URL

1.~2. C# winform 개발 & 테스트
    A. DB 에서 blob 형식으로 되어 있는 테이블을 읽는다. 테이블은 메일 전송 테이블과 첨부파일 테이블로 
        나눈다. (메뉴에 DB-테이블구조 > oracle > 1.1, 1,2 테이블 참조
    B. 메일전송 테이블(이하 SENDMAIL TABLE) 과 첨부파일 테이블(이하 FILESTORAGE) 을 읽어서 C# 
        SMTP.SEND 로 전송한다.(첨부파일은 BLOB 형식으로 보내진다. 소스는 아래와 같다.)

            MailMessage Email = new MailMessage();

            string mApplication = ConfigurationManager.AppSettings["ApplicationName"].ToString();
            string mMailFrom = dr["FROM_EMAIL"].ToString();
            string mMailTo = dr["TO_EMAIL"].ToString();
            string mMailSubject = dr["SUBJECT"].ToString();
            string mMailBody = dr["MESSAGE"].ToString();

            string mSMTPServer = ConfigurationManager.AppSettings["SMTP_SERVER"].ToString();
            int mSMTPPort = Int32.Parse(ConfigurationManager.AppSettings["SMTP_PORT"].ToString());

            string mSMTPUsername = ConfigurationManager.AppSettings["SMTP_ID"].ToString();
            string mSMTPPassword = ConfigurationManager.AppSettings["SMTP_PWD"].ToString();

            bool mSMTPSSL = false;

            MailAddress MailFrom = new MailAddress(mMailFrom, mApplication, 
                                                                         System.Text.Encoding.UTF8);
            Email.From = MailFrom;
            Email.To.Add(mMailTo);
            Email.Subject = mMailSubject;
            Email.SubjectEncoding = System.Text.Encoding.UTF8;
            Email.Body = mMailBody;
            Email.BodyEncoding = System.Text.Encoding.UTF8;

            //첨부파일 추가
            byte[] b = null;
            MemoryStream ms = null;

            try
            {
                DataTable dtAttach = Select_FileStorage(dbManager, dr);
                if (dtAttach.Rows.Count > 0)
                {
                    for (int i = 0; i < dtAttach.Rows.Count; i++)
                    {
                        b = (byte[])dtAttach.Rows[i]["FILE_ATTCH"];
                        ms = new MemoryStream(b);
                        ms.Position = 0;

                        Attachment data = new Attachment(ms, dtAttach.Rows[i]["FILE_NAME"].ToString(), 
                                                                         MediaTypeNames.Application.Octet);

                        //data.NameEncoding = Encoding.GetEncoding("euc-kr"); //첨부파일 한글깨짐 방지
                        Email.Attachments.Add(data);
                    }
                }

              SmtpPermission connectAccess = new SmtpPermission
                                                                                  (SmtpAccess.ConnectToUnrestrictedPort);

                SmtpClient SmtpMail = new SmtpClient(mSMTPServer, mSMTPPort);

                SmtpMail.EnableSsl = mSMTPSSL;
                SmtpMail.DeliveryMethod = SmtpDeliveryMethod.Network;
                SmtpMail.UseDefaultCredentials = false;

                SmtpMail.Credentials = new NetworkCredential(mSMTPUsername, mSMTPPassword);

                SmtpMail.Send(Email);

위 소스는 일반적으로 MSDN 이나 Google 에서 c# email attachment blob 으로 검색하면 많이 나오는 소스이다.

여기서 조금 뻘짓을 했는데 DB 에 BLOB 로 저장되어 있는 값을 DataTable 로 읽으면 안에 바이너리 형태로 string 형식으로 가져온다는 것을 몰랐다.
처음 소스는 저 부분을 object 로 가져와서 binary array 로 변환해서 이메일에 파일을 첨부하니 첨부는 됐다. 파일사이즈도 상세보기 말고 간략하게 보면 동일했다. 그런데 막상 파일을 열면 파일이 깨졌다.
파일 사이즈를 확인해 보니 파일 size가 미세하기 몇 byte 가 틀렸다.  binary 값을 확인해 보니 원본가 전혀 틀린 binary 여서 이때부터 맨땅에 헤딩을 했다.

encoding 도 해보고(euc-kr, utf-8/16,32 등), binary 변환도 하고 암튼 이것저것 다 해봤는데 안되다가 혹시나 하고
그냥 object 를 위와 같이 byte array 로 강제 형변환했더니 한번에 됐다. -_-; 내 하루가 그렇게 지나갔다.

결론은 저 BLOB 데이터를 디버깅 해서 봤으면 1~2분 만에 끝날 일을 구글링에 테스트에 뻘짓을 했다는 거다.
꼭 데이터를 확인하자!!!

* 추가 확인사항 : C#.NET 에서는 AUTH LOGIN 방식을 따로 프로퍼티로 설정하지 않고, 그냥 위처럼 
                        SmtpMail.Credentials = new NetworkCredential(mSMTPUsername, mSMTPPassword); 로 
                        넣으면 자동으로 AUTH LOGIN 방식으로 SMTP 서버에 전달된다. 이것 때문에도 뻘짓 많이 
                        했다..-_-;;; 뻘짓의 연속임
    
          C. 개발 완료 후 테스트하면 메일이 잘 나간다~ 첨부파일도 위에 부분만 확인해 주면 크게 문제는 없다. 
              C# winform 개발 및 테스트 완료 

 

 

반응형