Message.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Net / System / Net / Mail / Message.cs / 1598383 / Message.cs

                            using System; 
using System.Collections.Specialized;
using System.Net.Mime;
using System.Text;
using System.IO; 

namespace System.Net.Mail 
{ 
    /// 
    /// Summary description for Message. 
    /// 

    public enum MailPriority {
        Normal = 0, 
        Low = 1,
        High = 2 
    } 

 
    internal class Message
    {

        MailAddress from; 
        MailAddress sender;
        MailAddressCollection replyToList; 
        MailAddress replyTo; 
        MailAddressCollection to;
        MailAddressCollection cc; 
        MailAddressCollection bcc;
        MimeBasePart content;
        HeaderCollection headers;
        HeaderCollection envelopeHeaders; 
        string subject;
        Encoding subjectEncoding; 
        Encoding headersEncoding; 
        MailPriority priority = (MailPriority)(-1);
 

        internal Message() {
        }
 
        internal Message(string from, string to):this() {
            if (from == null) 
                throw new ArgumentNullException("from"); 

            if (to == null) 
                throw new ArgumentNullException("to");

            if (from == String.Empty)
                throw new ArgumentException(SR.GetString(SR.net_emptystringcall,"from"), "from"); 

            if (to == String.Empty) 
                throw new ArgumentException(SR.GetString(SR.net_emptystringcall,"to"), "to"); 

            this.from = new MailAddress(from); 
            MailAddressCollection collection = new MailAddressCollection();
            collection.Add(to);
            this.to = collection;
        } 

 
        internal Message(MailAddress from, MailAddress to):this() { 
            this.from = from;
            this.To.Add(to); 
        }


        public MailPriority Priority{ 
            get {
                return (((int)priority == -1)?MailPriority.Normal:priority); 
            } 
            set{
                priority = value; 
            }
        }

        internal MailAddress From { 
            get {
                return from; 
            } 
            set {
                if (value == null) { 
                    throw new ArgumentNullException("value");
                }
                from = value;
            } 
        }
 
 
        internal MailAddress Sender {
            get { 
                return sender;
            }
            set {
                sender = value; 
            }
        } 
 

        internal MailAddress ReplyTo { 
            get {
                return replyTo;
            }
            set { 
                replyTo = value;
            } 
        } 

        internal MailAddressCollection ReplyToList { 
            get {
                if (replyToList == null)
                    replyToList = new MailAddressCollection();
 
                return replyToList;
            } 
        } 

        internal MailAddressCollection To { 
            get {
                if (to == null)
                    to = new MailAddressCollection();
 
                return to;
            } 
        } 

        internal MailAddressCollection Bcc { 
            get {
                if (bcc == null)
                    bcc = new MailAddressCollection();
 
                return bcc;
            } 
        } 

        internal MailAddressCollection CC { 
            get {
                if (cc == null)
                    cc = new MailAddressCollection();
 
                return cc;
            } 
        } 

 
        internal string Subject {
            get {
                return subject;
            } 
            set {
                 if (value != null && MailBnfHelper.HasCROrLF(value)) { 
                     throw new ArgumentException(SR.GetString(SR.MailSubjectInvalidFormat)); 
                 }
                 subject = value; 

                 if (subject != null && subjectEncoding == null && !MimeBasePart.IsAscii(subject,false)) {
                     subjectEncoding = Encoding.GetEncoding(MimeBasePart.defaultCharSet);
                 } 
            }
        } 
 
        internal Encoding SubjectEncoding {
            get { 
                return subjectEncoding;
            }
            set {
                subjectEncoding = value; 
            }
        } 
 
        internal HeaderCollection Headers {
            get { 
                if (headers == null) {
                    headers = new HeaderCollection();
                    if(Logging.On)Logging.Associate(Logging.Web, this, headers);
                } 

                return headers; 
            } 
        }
 
        internal Encoding HeadersEncoding {
            get {
                return headersEncoding;
            } 
            set {
                headersEncoding = value; 
            } 
        }
 
        internal HeaderCollection EnvelopeHeaders {
            get {
                if (envelopeHeaders == null) {
                    envelopeHeaders = new HeaderCollection(); 
                    if(Logging.On)Logging.Associate(Logging.Web, this, envelopeHeaders);
                } 
 
                return envelopeHeaders;
            } 
        }


        internal virtual MimeBasePart Content { 
            get {
                return content; 
            } 
            set {
                if (value == null) { 
                    throw new ArgumentNullException("value");
                }

                content = value; 
            }
        } 
 

        internal void EmptySendCallback(IAsyncResult result) 
        {
            Exception e = null;

            if(result.CompletedSynchronously){ 
                return;
            } 
 
            EmptySendContext context = (EmptySendContext)result.AsyncState;
            try{ 
                context.writer.EndGetContentStream(result).Close();
            }
            catch(Exception ex){
                e = ex; 
            }
            context.result.InvokeCallback(e); 
        } 

 
        internal class EmptySendContext {
            internal EmptySendContext(BaseWriter writer, LazyAsyncResult result) {
                this.writer = writer;
                this.result = result; 
            }
 
            internal LazyAsyncResult result; 
            internal BaseWriter writer;
        } 



        internal virtual IAsyncResult BeginSend(BaseWriter writer, bool sendEnvelope, AsyncCallback callback, object state) { 

            PrepareHeaders(sendEnvelope); 
            writer.WriteHeaders(Headers); 

            if (Content != null) { 
                return Content.BeginSend(writer, callback, state);
            }
            else{
                LazyAsyncResult result = new LazyAsyncResult(this,state,callback); 
                IAsyncResult newResult = writer.BeginGetContentStream(EmptySendCallback, new EmptySendContext(writer,result));
                if(newResult.CompletedSynchronously){ 
                    writer.EndGetContentStream(newResult).Close(); 
                }
                return result; 
            }
        }

 
        internal virtual void EndSend(IAsyncResult asyncResult){
            if (asyncResult == null) { 
                throw new ArgumentNullException("asyncResult"); 
            }
 
            if (Content != null) {
                Content.EndSend(asyncResult);
            }
            else{ 
                LazyAsyncResult castedAsyncResult = asyncResult as LazyAsyncResult;
 
                if (castedAsyncResult == null || castedAsyncResult.AsyncObject != this) { 
                    throw new ArgumentException(SR.GetString(SR.net_io_invalidasyncresult));
                } 

                if (castedAsyncResult.EndCalled) {
                    throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndSend"));
                } 

                castedAsyncResult.InternalWaitForCompletion(); 
                castedAsyncResult.EndCalled = true; 
                if (castedAsyncResult.Result is Exception) {
                    throw (Exception)castedAsyncResult.Result; 
                }
            }
        }
 
        internal virtual void Send(BaseWriter writer, bool sendEnvelope) {
 
            if (sendEnvelope) { 
                PrepareEnvelopeHeaders(sendEnvelope);
                writer.WriteHeaders(EnvelopeHeaders); 
            }

            PrepareHeaders(sendEnvelope);
            writer.WriteHeaders(Headers); 

            if (Content != null) { 
                Content.Send(writer); 
            }
            else{ 
                writer.GetContentStream().Close();
            }
        }
 
        internal void PrepareEnvelopeHeaders(bool sendEnvelope) {
 
            if (this.headersEncoding == null) { 
                this.headersEncoding = Encoding.GetEncoding(MimeBasePart.defaultCharSet);
            } 

            EncodeHeaders(this.EnvelopeHeaders);

            // Dev10 #430372: only add X-Sender header if it wasn't already set by the user 
            string xSenderHeader = MailHeaderInfo.GetString(MailHeaderID.XSender);
            if (!IsHeaderSet(xSenderHeader)) { 
                EnvelopeHeaders.InternalSet(xSenderHeader, From.Encode(xSenderHeader.Length)); 
            }
 
            EnvelopeHeaders.Remove(MailHeaderInfo.GetString(MailHeaderID.XReceiver));
            foreach (MailAddress address in To)
                EnvelopeHeaders.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.XReceiver),
                                            address.Encode(MailHeaderInfo.GetString(MailHeaderID.XReceiver).Length)); 
            foreach (MailAddress address in CC)
                EnvelopeHeaders.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.XReceiver), 
                                            address.Encode(MailHeaderInfo.GetString(MailHeaderID.XReceiver).Length)); 
            foreach (MailAddress address in Bcc)
                EnvelopeHeaders.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.XReceiver), 
                                            address.Encode(MailHeaderInfo.GetString(MailHeaderID.XReceiver).Length));
        }

        internal void PrepareHeaders(bool sendEnvelope) { 

            if (this.headersEncoding == null) { 
                this.headersEncoding = Encoding.GetEncoding(MimeBasePart.defaultCharSet); 
            }
 
            //ContentType is written directly to the stream so remove potential user duplicate
            Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.ContentType));

            Headers[MailHeaderInfo.GetString(MailHeaderID.MimeVersion)] = "1.0"; 

            // add sender to headers first so that it is written first to allow the IIS smtp svc to 
            // send MAIL FROM with the sender if both sender and from are present 
            if(Sender != null){
                Headers.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.Sender), 
                                    Sender.Encode(MailHeaderInfo.GetString(MailHeaderID.Sender).ToString().Length));
            }
            else{
                Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.Sender)); 
            }
 
            Headers.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.From), 
                               From.Encode(MailHeaderInfo.GetString(MailHeaderID.From).ToString().Length));
 
            if (To.Count > 0)
            {
                string addresses = To.Encode(MailHeaderInfo.GetString(MailHeaderID.To).Length);
                Headers.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.To), addresses); 
            }
            else 
                Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.To)); 

            if (CC.Count > 0) 
                Headers.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.Cc),
                    CC.Encode(MailHeaderInfo.GetString(MailHeaderID.Cc).Length));
            else
                Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.Cc)); 

            if (ReplyTo != null) { 
                Headers.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.ReplyTo), 
                    ReplyTo.Encode(MailHeaderInfo.GetString(MailHeaderID.ReplyTo).Length));
            } 
            else if (ReplyToList.Count > 0) {
                Headers.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.ReplyTo),
                    ReplyToList.Encode(MailHeaderInfo.GetString(MailHeaderID.ReplyTo).Length));
            } 
            else {
                Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.ReplyTo)); 
            } 

            Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.Bcc)); 

            if (priority == MailPriority.High){
                Headers[MailHeaderInfo.GetString(MailHeaderID.XPriority)] = "1";
                Headers[MailHeaderInfo.GetString(MailHeaderID.Priority)] = "urgent"; 
                Headers[MailHeaderInfo.GetString(MailHeaderID.Importance)] = "high";
            } 
            else if (priority == MailPriority.Low){ 
                Headers[MailHeaderInfo.GetString(MailHeaderID.XPriority)] = "5";
                Headers[MailHeaderInfo.GetString(MailHeaderID.Priority)] = "non-urgent"; 
                Headers[MailHeaderInfo.GetString(MailHeaderID.Importance)] = "low";
               }
            //if the priority was never set, allow the app to set the headers directly.
            else if (((int)priority) != -1){ 
                Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.XPriority));
                Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.Priority)); 
                Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.Importance)); 
            }
 
            Headers.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.Date),
                MailBnfHelper.GetDateTimeString(DateTime.Now, null));

 
            if (!string.IsNullOrEmpty(subject)){
                Headers.InternalAdd(MailHeaderInfo.GetString(MailHeaderID.Subject), 
                    MimeBasePart.EncodeHeaderValue(subject, subjectEncoding, 
                    MimeBasePart.ShouldUseBase64Encoding(subjectEncoding),
                    MailHeaderID.Subject.ToString().Length)); 
            }
            else{
                Headers.Remove(MailHeaderInfo.GetString(MailHeaderID.Subject));
            } 

            EncodeHeaders(this.headers); 
        } 

        internal void EncodeHeaders(HeaderCollection headers) { 

            if (this.headersEncoding == null) {
                this.headersEncoding = Encoding.GetEncoding(MimeBasePart.defaultCharSet);
            } 

            System.Diagnostics.Debug.Assert(this.headersEncoding != null); 
 
            for (int i = 0; i < headers.Count; i++) {
                string headerName = headers.GetKey(i); 

                //certain well-known values are encoded by PrepareHeaders and PrepareEnvelopeHeaders
                //so we can ignore them because either we encoded them already or there is no
                //way for the user to have set them.  If a header is well known and user settable then 
                //we should encode it here, otherwise we have already encoded it if necessary
                if (!MailHeaderInfo.IsUserSettable(headerName)) { 
                    continue; 
                }
 
                string[] values = headers.GetValues(headerName);
                string encodedValue = String.Empty;
                for (int j = 0; j < values.Length; j++) {
                    //encode if we need to 
                    if (MimeBasePart.IsAscii(values[j], false)) {
                        encodedValue = values[j]; 
                    } 
                    else {
                        encodedValue = MimeBasePart.EncodeHeaderValue(values[j], 
                                                        this.headersEncoding,
                                                        MimeBasePart.ShouldUseBase64Encoding(this.headersEncoding),
                                                        headerName.Length);
                    } 

                    //potentially there are multiple values per key 
                    if (j == 0) { 
                        //if it's the first or only value, set will overwrite all the values assigned to that key
                        //which is fine since we have them stored in values[] 
                        headers.Set(headerName, encodedValue);
                    }
                    else {
                        //this is a subsequent key, so we must Add it since the first key will have overwritten the 
                        //other values
                        headers.Add(headerName, encodedValue); 
                    } 

                } 
            }
        }

        private bool IsHeaderSet(string headerName) 
        {
            for (int i = 0; i < Headers.Count; i++) 
            { 
                if (string.Compare(Headers.GetKey(i), headerName,
                    StringComparison.InvariantCultureIgnoreCase) == 0) 
                {
                    return true;
                }
            } 
            return false;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK