최근 고객이 고민하던 것을 우연히 해결하게 되어 몇 마디 끄적여 봅니다. 항상 우리나라와 쪽발이놈 나라(일본), 떼놈 나라(중국) 같이 복잡한 2바이트 문자를 사용하는 국가에서는 항상 자국어에 대한 처리로 고민하게 됩니다. 초기 인터넷이 보급될 때 한글로 메일을 보내기 위해 다양한 삽질을 했던 기억이 아주 가물가물 하네요. 이번 글은 닷넷에서 SMTP(Simple Mail Transfer Protocol) 메일을 보낼 때 한글 파일명을 가진 파일을 첨부할 때 발생하는 문제를 해결하는 방법에 대해 간단히 몇 마디 적어 봅니다.
Attaching Korean Named File to SMTP Mail
 |
닷넷은 풍부한 프로그래밍 환경을 제공한다. 이 말은 닷넷 이전의 개발환경들, 즉 VB 6.0 이나 델파이, 파워 빌더와 같은 개발환경에 비해 개발을 보다 적은 코드로 쉽게 할 수 있다는 말이 되겠다. VC++로 이벤트 로그에 로그 하나 남기려고 하면 졸라 많은 코드를 작성해야만 한다. 하지만 닷넷은 달랑 한 줄의 코드로 충분히 이벤트 로그에 흔적을 남길 수 있는 것이다.
지난 친절한 닷넷씨 글에서도 친절한 닷넷의 API를 하나 알아보았다. 이번에는 항상 우리 개발자들의 골머리를 앓게 하는 한글 처리에 대한 이야기를 해볼까 한다.
요는 이렇다. 메일을 발송하는 코드는 다양한 어플리케이션에서 상당히 자주 등장한다. 닷넷 프레임워크 1.1까지는 SMTP 메일을 발송하는 클래스들이 System.Web.Mail 네임스페이스에서 제공되었었다. 이건 뭐 독자들도 한두 번쯤은 써 보았을 것이다. 이 네임스페이스는 달랑 클래스 몇 개로만 구성되어 있으며 실제로는 CDO for Windows 2000 이라 불리는 COM 객체를 얇게 감싸고 있을 뿐이다.
닷넷 프레임워크 2.0에는 SMTP 메일을 위해서는 System.Net.Mail 네임스페이스를 사용할 것을 권장하고 있다. 이 네임스페이스는 다양한 클래스들을 통해 SMTP 프로토콜을 순수 닷넷 코드로 구현해 놓았다.
그래서 뭐가 달라졌냐고? SMTP 메일에 대해 다양한 제어가 가능하게 되었다는 말이다. 이러한 기능에 대해서는 다음 기회에 상세히 살펴보기로 하고 이번에는 파일 첨부에 대해서만 살펴보도록 하겠다. |
Attaching File to Mail
System.Net.Mail 네임스페이스를 사용하는 방법은 System.Web.Mail 네임스페이스를 사용하는 것과 기본적으로 비슷하지만 훨씬 많은 클래스와 풍부한 속성, 메쏘드를 통해 SMTP 메일을 제어 할 수 있다. System.Net.Mail 네임스페이스를 사용하여 파일을 첨부하는 전형적인 예제코드는 리스트1 과 같다.
Attachment attach1 = new Attachment(FileNameEn); // 영문 이름의 파일 첨부
Attachment attach2 = new Attachment(FileNameKo); // 한글 이름의 파일 첨부
MailMessage message = new MailMessage();
SmtpClient client = new SmtpClient(Server); // 메일 서버 설정 포함
message.From = new MailAddress(From);
message.To.Add(new MailAddress(To));
message.Subject = Subject;
message.Body = Body;
message.Attachments.Add(attach1);
message.Attachments.Add(attach2);
client.Send(message); // 메일 발송
리스트1. System.Net.Mail 을 이용한 메일 전송 및 파일 첨부
첨부를 위해서는 Attachment 객체를 생성해야 하며, 이 인스턴스를 MailMessage 객체의 Attachments 컬렉션에 추가해야만 한다. 이는 예전의 System.Web.Mail 네임스페이스를 사용하는 것과 매우 비슷하다.
이렇게 코딩 하면 메일을 발송하는데 별다른 지장이 없다. 물론, 메일 서버에 로그온 해야 하거나 메일 주소 대신에 이름(friendly name)이 표시되어야 하는 경우 약간의 추가 코딩이 필요하지만 여기서는 언급하지 않겠다.
대부분의 경우에 리스트1의 코드는 매우 잘 작동할 것이다. 하지만 몇몇 SMTP 서버에서 한글 이름을 가진 파일이 첨부되었을 때 한글 파일명이 깨지는 경우가 발생하곤 한다. 기본적으로 System.Net.Mail 과 System.Web.Mail 이 한글 파일 이름을 인코딩(encoding) 해주지만 이 인코딩을 인식하지 못하는 SMTP 서버가 존재할 수 있기 때문이다.
Using NameEncoding property
System.Web.Mail을 사용하는 경우 이를 해결하는 방법이 뾰족하지 않았다(적어도 필자가 아는 한...). CDO for Windows 2000을 워낙에 간단히 감싸놓은 것인지라 클래스와 속성들이 너무 빈약하기 때문이다. 반면 System.Net.Mail 네임스페이스는 SMTP 프로토콜을 자체 구현해 놓은 것이므로 메일과 MIME이 필요로 하는 대부분의 설정을 수행할 수 있다.
파일 첨부에서 한글 파일명이 깨지는 것을 막기 위해 Attachment 클래스는 NameEncoding 속성을 제공한다. 이 속성을 이용하여 파일 이름을 인코딩 해주면 된다. 우리나라에서 대다수의 SMTP 메일 서버는 euc-kr 인코딩을 즐겨 사용하므로 파일 명에 문제가 발생하는 경우, 이 인코딩을 설정해 주면 된다. Euc-kr 이 주로 사용되는 이유로 대다수의 SMTP 메일 서버가 UNIX 기반이고 UNIX 동네에서는 euc-kr 인코딩을 많이 사용하기 때문으로 보인다.
파일 첨부에서 파일 명을 인코딩 하기 위한 닷넷 코드는 졸라 간단하다. 앞서 언급한 대로 단순히 NameEncoding을 설정해 주기만 하면 된다.
attach2.NameEncoding = System.Text.Encoding.GetEncoding("euc-kr");
Epilog
한글 처리는 항상 개발자의 짐이 되곤 한다. 그나마 요즘에는 대부분의 개발 플랫폼이나 소프트웨어들이 다양한 언어에 대한 지원을 제공하기 때문에 좀 나아졌지만, 한글이 깨지는 문제는 언제 어디서나 발생할 수 있다. 그런데 이러한 한글 처리 방법이 그때 그때 환경이나 제품, 제품의 버전마다 조금씩 다르다는 점이다. 예를 들어, 이름에 한글이 포함된 파일을 다운로드 해줄 때의 처리 방식이 IE 와 Firefox, Netscape 가 서로 다르기도 하며 좀 심할 때는 버전에 따라 다르기도 하다.
많은 수의 개발자들이 힘들어 하는 것이 바로 이 부분 때문이라 생각한다. 또한 해결책 역시 뾰족하지 않다는 것인데... 시간이 흘러감에 따라 엿같은 US-ASCII 가 아닌 UTF-8 같은 문자셋이 널리 사용되기를 기다리던가 아니면 다양한 경험을 통해 그때 그때 대처하는 수 밖에 없는 듯 하다. 우리 개발자들이 삽질하면 또 한 삽질 하지 않는가? -_-;