创建基于MailKit和MimeKit的.NET基础邮件服务

邮件服务是一般的系统都会拥有和需要的功能,但是对于.NET项目来说,邮件服务的创建和使用会较为的麻烦。.NET对于邮件功能提供了System.Net.Mail用于创建邮件服务,该基础服务提供邮件的基础操作,并且使用也较为的简单。对于真正将该功能使用于项目的人,就会慢慢发现其中的优缺点,甚至有些时候不能忍受其中的问题。在这里介绍一种微软用于替代System.Net.Mail的邮件服务组件MailKit和MimeKit,官网地址:http://www.mimekit.net/。GitHub地址:https://github.com/jstedfast/MimeKit。下面就具体的介绍一下。

  一.MailKit和MimeKit基础概述:

MailKit组件的支持的客户端类型比较多,例如SMTP客户端、POP3客户端、IMAP4客户端。该组件是一个跨平台的Email组件,该组件支持.NET 4.0,.NET 4.5,Xamarin.Android,Xamarin.iOS,Windows Phone 8.1等等平台。

MimeKit提供了一个MIME解析器,组件具备的解析特性灵活、性能高、很好的处理各种各样的破碎的MIME格式化。MimeKit的性能实际上与GMime相当。

该组件在安全性的还是比较高的,处理安全的方式较多,SASL认证、支持S / MIME v3.2、支持OpenPGP、支持DKIM签名等等方式。Mailkit组件可以通过CancellationToken取消对应的操作,CancellationToken传播应取消操作的通知,一个的CancellationToken使线程,线程池工作项目之间,或取消合作任务的对象。过实例化CancellationTokenSource对象来创建取消令牌,该对象管理从其CancellationTokenSource.Token属性检索的取消令牌。然后,将取消令牌传递到应该收到取消通知的任意数量的线程,任务或操作。令牌不能用于启动取消。

MailKit组件支持异步操作,在内部编写的有关I/O异步操作的类。

  二.创建基础邮件服务:

介绍过MailKit和MimeKit组建的基础信息,接下来就介绍一下如何使用两个组件的基本功能,在这里我将基本操作做了一个简单的封装,一般的项目可以直接引用封装好的类,大家可以根据实际的情况对该组件进行扩展。

1.邮件发送基础服务API

    /// <summary>
    /// 邮件服务API
    /// </summary>
    public static class MailServiceApi
    {
        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="mailBodyEntity">邮件基础信息</param>
        /// <param name="sendServerConfiguration">发件人基础信息</param>
        public static SendResultEntity SendMail(MailBodyEntity mailBodyEntity,
            SendServerConfigurationEntity sendServerConfiguration)
        {
            if (sendServerConfiguration == null)
            {
                throw new ArgumentNullException();
            }

            if (sendServerConfiguration == null)
            {
                throw new ArgumentNullException();
            }

            var sendResultEntity = new SendResultEntity();

            using (var client = new SmtpClient(new ProtocolLogger(CreateMailLog())))
            {
                client.ServerCertificateValidationCallback = (s, c, h, e) => true;

                Connection(mailBodyEntity, sendServerConfiguration, client, sendResultEntity);

                if (sendResultEntity.ResultStatus == false)
                {
                    return sendResultEntity;
                }

                SmtpClientBaseMessage(client);

                Authenticate(mailBodyEntity, sendServerConfiguration, client, sendResultEntity);

                if (sendResultEntity.ResultStatus == false)
                {
                    return sendResultEntity;
                }

                Send(mailBodyEntity, sendServerConfiguration, client, sendResultEntity);

                if (sendResultEntity.ResultStatus == false)
                {
                    return sendResultEntity;
                }

                client.Disconnect(true);
            }

            return sendResultEntity;
        }

        /// <summary>
        /// 连接服务器
        /// </summary>
        /// <param name="mailBodyEntity">邮件内容</param>
        /// <param name="sendServerConfiguration">发送配置</param>
        /// <param name="client">客户端对象</param>
        /// <param name="sendResultEntity">发送结果</param>
        public static void Connection(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration,
            SmtpClient client, SendResultEntity sendResultEntity)
        {
            try
            {
                client.Connect(sendServerConfiguration.SmtpHost, sendServerConfiguration.SmtpPort);
            }
            catch (SmtpCommandException ex)
            {
                sendResultEntity.ResultInformation = $"尝试连接时出错:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (SmtpProtocolException ex)
            {
                sendResultEntity.ResultInformation = $"尝试连接时的协议错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (Exception ex)
            {
                sendResultEntity.ResultInformation = $"服务器连接错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
        }

        /// <summary>
        /// 账户认证
        /// </summary>
        /// <param name="mailBodyEntity">邮件内容</param>
        /// <param name="sendServerConfiguration">发送配置</param>
        /// <param name="client">客户端对象</param>
        /// <param name="sendResultEntity">发送结果</param>
        public static void Authenticate(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration,
            SmtpClient client, SendResultEntity sendResultEntity)
        {
            try
            {
                client.Authenticate(sendServerConfiguration.SenderAccount, sendServerConfiguration.SenderPassword);
            }
            catch (AuthenticationException ex)
            {
                sendResultEntity.ResultInformation = $"无效的用户名或密码:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (SmtpCommandException ex)
            {
                sendResultEntity.ResultInformation = $"尝试验证错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (SmtpProtocolException ex)
            {
                sendResultEntity.ResultInformation = $"尝试验证时的协议错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (Exception ex)
            {
                sendResultEntity.ResultInformation = $"账户认证错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="mailBodyEntity">邮件内容</param>
        /// <param name="sendServerConfiguration">发送配置</param>
        /// <param name="client">客户端对象</param>
        /// <param name="sendResultEntity">发送结果</param>
        public static void Send(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration,
            SmtpClient client, SendResultEntity sendResultEntity)
        {
            try
            {
                client.Send(MailMessage.AssemblyMailMessage(mailBodyEntity));
            }
            catch (SmtpCommandException ex)
            {
                switch (ex.ErrorCode)
                {
                    case SmtpErrorCode.RecipientNotAccepted:
                        sendResultEntity.ResultInformation = $"收件人未被接受:{ex.Message}";
                        break;
                    case SmtpErrorCode.SenderNotAccepted:
                        sendResultEntity.ResultInformation = $"发件人未被接受:{ex.Message}";
                        break;
                    case SmtpErrorCode.MessageNotAccepted:
                        sendResultEntity.ResultInformation = $"消息未被接受:{ex.Message}";
                        break;
                }
                sendResultEntity.ResultStatus = false;
            }
            catch (SmtpProtocolException ex)
            {
                sendResultEntity.ResultInformation = $"发送消息时的协议错误:{ex.Message}";
                sendResultEntity.ResultStatus = false;
            }
            catch (Exception ex)
            {
                sendResultEntity.ResultInformation = $"邮件接收失败:{ex.Message}";
                sendResultEntity.ResultStatus = false;
            }
        }

        /// <summary>
        /// 获取SMTP基础信息
        /// </summary>
        /// <param name="client">客户端对象</param>
        /// <returns></returns>
        public static MailServerInformation SmtpClientBaseMessage(SmtpClient client)
        {
            var mailServerInformation = new MailServerInformation
            {
                Authentication = client.Capabilities.HasFlag(SmtpCapabilities.Authentication),
                BinaryMime = client.Capabilities.HasFlag(SmtpCapabilities.BinaryMime),
                Dsn = client.Capabilities.HasFlag(SmtpCapabilities.Dsn),
                EightBitMime = client.Capabilities.HasFlag(SmtpCapabilities.EightBitMime),
                Size = client.MaxSize
            };

            return mailServerInformation;
        }

        /// <summary>
        /// 创建邮件日志文件
        /// </summary>
        /// <returns></returns>
        public static string CreateMailLog()
        {
            var logPath = AppDomain.CurrentDomain.BaseDirectory + "/DocumentLog/" +
                Guid.NewGuid() + ".txt";

            if (File.Exists(logPath)) return logPath;
            var fs = File.Create(logPath);
            fs.Close();
            return logPath;
        }
    }

2.组装邮件消息:

    /// <summary>
    /// 邮件信息
    /// </summary>
    public static class MailMessage
    {
        /// <summary>
        /// 组装邮件文本/附件邮件信息
        /// </summary>
        /// <param name="mailBodyEntity">邮件消息实体</param>
        /// <returns></returns>
        public static MimeMessage AssemblyMailMessage(MailBodyEntity mailBodyEntity)
        {
            if (mailBodyEntity == null)
            {
                throw new ArgumentNullException(nameof(mailBodyEntity));
            }

            var message = new MimeMessage();

            //设置邮件基本信息
            SetMailBaseMessage(message, mailBodyEntity);

            var multipart = new Multipart("mixed");

            //插入文本消息
            if (string.IsNullOrEmpty(mailBodyEntity.MailTextBody) == false)
            {
                var alternative = new MultipartAlternative
                {
                    AssemblyMailTextMessage(mailBodyEntity.MailTextBody, mailBodyEntity.MailBodyType)
                 };

                multipart.Add(alternative);
            }

            //插入附件
            if (mailBodyEntity.MailFilePath != null && File.Exists(mailBodyEntity.MailFilePath) == false)
            {
                var mimePart = AssemblyMailAttachmentMessage(mailBodyEntity.MailFileType, mailBodyEntity.MailFileSubType,
                     mailBodyEntity.MailFilePath);

                multipart.Add(mimePart);
            }

            //组合邮件内容
            message.Body = multipart;

            return message;
        }

        /// <summary>
        /// 设置邮件基础信息
        /// </summary>
        /// <param name="minMessag"></param>
        /// <param name="mailBodyEntity"></param>
        /// <returns></returns>
        public static MimeMessage SetMailBaseMessage(MimeMessage minMessag, MailBodyEntity mailBodyEntity)
        {
            if (minMessag == null)
            {
                throw new ArgumentNullException();
            }

            if (mailBodyEntity == null)
            {
                throw new ArgumentNullException();
            }

            //插入发件人
            minMessag.From.Add(new MailboxAddress(mailBodyEntity.Sender, mailBodyEntity.SenderAddress));

            //插入收件人
            foreach (var recipients in mailBodyEntity.Recipients)
            {
                minMessag.To.Add(new MailboxAddress(recipients));
            }

            //插入抄送人
            foreach (var cC in mailBodyEntity.Cc)
            {
                minMessag.Cc.Add(new MailboxAddress(cC));
            }

            //插入主题
            minMessag.Subject = mailBodyEntity.Subject;

            return minMessag;
        }

        /// <summary>
        /// 组装邮件文本信息
        /// </summary>
        /// <param name="mailBody">邮件文本内容</param>
        /// <param name="textPartType">邮件文本类型(plain,html,rtf,xml)</param>
        /// <returns></returns>
        public static TextPart AssemblyMailTextMessage(string mailBody, string textPartType)
        {
            if (string.IsNullOrEmpty(mailBody))
            {
                throw new ArgumentNullException();
            }

            if (string.IsNullOrEmpty(textPartType))
            {
                throw new ArgumentNullException();
            }

            var textBody = new TextPart(textPartType)
            {
                Text = mailBody
            };

            return textBody;
        }

        /// <summary>
        /// 组装邮件附件信息
        /// </summary>
        /// <param name="fileAttachmentType">附件类型(image,application)</param>
        /// <param name="fileAttachmentSubType">附件子类型 </param>
        /// <param name="fileAttachmentPath">附件路径</param>
        /// <returns></returns>
        public static MimePart AssemblyMailAttachmentMessage(string fileAttachmentType, string fileAttachmentSubType, string fileAttachmentPath)
        {
            if (string.IsNullOrEmpty(fileAttachmentSubType))
            {
                throw new ArgumentNullException();
            }

            if (string.IsNullOrEmpty(fileAttachmentType))
            {
                throw new ArgumentNullException();
            }

            if (string.IsNullOrEmpty(fileAttachmentPath))
            {
                throw new ArgumentNullException();
            }

            var attachment = new MimePart(fileAttachmentType, fileAttachmentSubType)
            {
                Content = new MimeContent(File.OpenRead(fileAttachmentPath)),
                ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
                ContentTransferEncoding = ContentEncoding.Base64,
                FileName = Path.GetFileName(fileAttachmentPath)
            };

            return attachment;
        }

    }

3.邮件基础服务实体:

    /// <summary>
    /// 邮件内容实体
    /// </summary>
    public class MailBodyEntity
    {
        /// <summary>
        /// 邮件文本内容
        /// </summary>
        public string MailTextBody { get; set; }

        /// <summary>
        /// 邮件内容类型
        /// </summary>
        public string MailBodyType { get; set; }

        /// <summary>
        /// 邮件附件文件类型
        /// </summary>
        public string MailFileType { get; set; }

        /// <summary>
        /// 邮件附件文件子类型
        /// </summary>
        public string MailFileSubType { get; set; }

        /// <summary>
        /// 邮件附件文件路径
        /// </summary>
        public string MailFilePath { get; set; }

        /// <summary>
        /// 收件人
        /// </summary>
        public List<string> Recipients { get; set; }

        /// <summary>
        /// 抄送
        /// </summary>
        public List<string> Cc { get; set; }

        /// <summary>
        /// 发件人
        /// </summary>
        public string Sender { get; set; }

        /// <summary>
        /// 发件人地址
        /// </summary>
        public string SenderAddress { get; set; }

        /// <summary>
        /// 邮件主题
        /// </summary>
        public string Subject { get; set; }

        /// <summary>
        /// 邮件内容
        /// </summary>
        public string Body { get; set; }
    }

    /// <summary>
    /// 邮件服务器基础信息
    /// </summary>
    public class MailServerInformation
    {
        /// <summary>
        /// SMTP服务器支持SASL机制类型
        /// </summary>
        public bool Authentication { get; set; }

        /// <summary>
        /// SMTP服务器对消息的大小
        /// </summary>
        public uint Size { get; set; }

        /// <summary>
        /// SMTP服务器支持传递状态通知
        /// </summary>
        public bool Dsn { get; set; }

        /// <summary>
        /// SMTP服务器支持Content-Transfer-Encoding
        /// </summary>
        public bool EightBitMime { get; set; }

        /// <summary>
        /// SMTP服务器支持Content-Transfer-Encoding
        /// </summary>
        public bool BinaryMime { get; set; }

        /// <summary>
        /// SMTP服务器在消息头中支持UTF-8
        /// </summary>
        public string UTF8 { get; set; }
    }

    /// <summary>
    /// 邮件发送结果
    /// </summary>
    public class SendResultEntity
    {
        /// <summary>
        /// 结果信息
        /// </summary>
        public string ResultInformation { get; set; } = "发送成功!";

        /// <summary>
        /// 结果状态
        /// </summary>
        public bool ResultStatus { get; set; } = true;
    }

    /// <summary>
    /// 邮件发送服务器配置
    /// </summary>
    public class SendServerConfigurationEntity
    {
        /// <summary>
        /// 邮箱SMTP服务器地址
        /// </summary>
        public string SmtpHost { get; set; }

        /// <summary>
        /// 邮箱SMTP服务器端口
        /// </summary>
        public int SmtpPort { get; set; }

        /// <summary>
        /// 是否启用IsSsl
        /// </summary>
        public bool IsSsl { get; set; }

        /// <summary>
        /// 邮件编码
        /// </summary>
        public string MailEncoding { get; set; }

        /// <summary>
        /// 发件人账号
        /// </summary>
        public string SenderAccount { get; set; }

        /// <summary>
        /// 发件人密码
        /// </summary>
        public string SenderPassword { get; set; }

    }

上面提供了借助MailKit组建创建发送邮件服务,分别是创建邮件服务器连接,组装邮件基础信息,邮件基础实体。发送邮件的基础服务比较的多,下面介绍一下邮件的接收。

    /// <summary>
    /// 跟投邮件服务API
    /// </summary>
    public static class ReceiveEmailServiceApi
    {
        /// <summary>
        /// 设置发件人信息
        /// </summary>
        /// <returns></returns>
        public static SendServerConfigurationEntity SetSendMessage()
        {
            var sendServerConfiguration = new SendServerConfigurationEntity
            {
                SmtpHost = ConfigurationManager.AppSettings["SmtpServer"],
                SmtpPort = int.Parse(ConfigurationManager.AppSettings["SmtpPort"]),
                IsSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["IsSsl"]),
                MailEncoding = ConfigurationManager.AppSettings["MailEncoding"],
                SenderAccount = ConfigurationManager.AppSettings["SenderAccount"],
                SenderPassword = ConfigurationManager.AppSettings["SenderPassword"]
            };
            return sendServerConfiguration;
        }

        /// <summary>
        /// 接收邮件
        /// </summary>
        public static void ReceiveEmail()
        {
            var sendServerConfiguration = SetSendMessage();

            if (sendServerConfiguration == null)
            {
                throw new ArgumentNullException();
            }

            using (var client = new ImapClient(new ProtocolLogger(CreateMailLog())))
            {
                client.Connect(sendServerConfiguration.SmtpHost, sendServerConfiguration.SmtpPort,
                    SecureSocketOptions.SslOnConnect);
                client.Authenticate(sendServerConfiguration.SenderAccount, sendServerConfiguration.SenderPassword);
                client.Inbox.Open(FolderAccess.ReadOnly);
                var uids = client.Inbox.Search(SearchQuery.All);
                foreach (var uid in uids)
                {
                    var message = client.Inbox.GetMessage(uid);
                    message.WriteTo($"{uid}.eml");
                }

                client.Disconnect(true);
            }
        }

        /// <summary>
        /// 下载邮件内容
        /// </summary>
        public static void DownloadBodyParts()
        {
            var sendServerConfiguration = SetSendMessage();

            using (var client = new ImapClient())
            {
                client.Connect(sendServerConfiguration.SmtpHost, sendServerConfiguration.SmtpPort,
                    SecureSocketOptions.SslOnConnect);
                client.Authenticate(sendServerConfiguration.SenderAccount, sendServerConfiguration.SenderPassword);
                client.Inbox.Open(FolderAccess.ReadOnly);

                // 搜索Subject标题包含“MimeKit”或“MailKit”的邮件
                var query = SearchQuery.SubjectContains("MimeKit").Or(SearchQuery.SubjectContains("MailKit"));
                var uids = client.Inbox.Search(query);

                // 获取搜索结果的摘要信息(我们需要UID和BODYSTRUCTURE每条消息,以便我们可以提取文本正文和附件)
                var items = client.Inbox.Fetch(uids, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure);

                foreach (var item in items)
                {
                    // 确定一个目录来保存内容
                    var directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "/MailBody", item.UniqueId.ToString());

                    Directory.CreateDirectory(directory);

                    // IMessageSummary.TextBody是一个便利的属性,可以为我们找到“文本/纯文本”的正文部分
                    var bodyPart = item.TextBody;

                    // 下载‘text / plain‘正文部分
                    var body = (TextPart) client.Inbox.GetBodyPart(item.UniqueId, bodyPart);

                    // TextPart.Text是一个便利的属性,它解码内容并将结果转换为我们的字符串
                    var text = body.Text;

                    File.WriteAllText(Path.Combine(directory, "body.txt"), text);

                    // 现在遍历所有附件并将其保存到磁盘
                    foreach (var attachment in item.Attachments)
                    {
                        // 像我们对内容所做的那样下载附件
                        var entity = client.Inbox.GetBodyPart(item.UniqueId, attachment);

                        // 附件可以是message / rfc822部件或常规MIME部件
                        var messagePart = entity as MessagePart;
                        if (messagePart != null)
                        {
                            var rfc822 = messagePart;

                            var path = Path.Combine(directory, attachment.PartSpecifier + ".eml");

                            rfc822.Message.WriteTo(path);
                        }
                        else
                        {
                            var part = (MimePart) entity;

                            // 注意:这可能是空的,但大多数会指定一个文件名
                            var fileName = part.FileName;

                            var path = Path.Combine(directory, fileName);

                            // decode and save the content to a file
                            using (var stream = File.Create(path))
                                part.Content.DecodeTo(stream);
                        }
                    }
                }

                client.Disconnect(true);
            }
        }

        /// <summary>
        /// 创建邮件日志文件
        /// </summary>
        /// <returns></returns>
        public static string CreateMailLog()
        {
            var logPath = AppDomain.CurrentDomain.BaseDirectory + "/DocumentLog/" +
                DateTime.Now.ToUniversalTime().ToString(CultureInfo.InvariantCulture) + ".txt";

            if (File.Exists(logPath)) return logPath;
            var fs = File.Create(logPath);
            fs.Close();
            return logPath;

        }
    }

上面只是简单的介绍了邮件的接收,如果需要更加深入的了解功能,可以进一步对组件源码进行解析,该组件的文档为较为的丰富。

  三.组件使用感悟:

MailKit和MimeKit组件在项目的使用中较为的便捷,基本包含了所有的基础邮件服务操作。组件提供的SmtpClient类提供的功能很丰富,例如连接邮件服务器,邮件账户认证,组装邮件消息,获取邮件服务器配置信息等等方法的提供,可以让我们在项目中快速的获取邮件服务的所有信息。

使用过邮件功能的项目 都会有困扰,客户端与邮件服务器的连接是否成功,以及邮件是否发送成功状态没有办法很快的获取,只能根据邮件服务器返回的一场状态进行判断。但是MailKit提供对应的方法和异常类,对邮件服务器返回的异常信息进行解析,客户端可以根据这些异常类获取邮件状态。

MailKit组件的提供了ProtocolLogger类,该类用于记录SMTP操作基础信息,该类作用为记录邮件服务日志。在邮件发送完毕后,需要及时的关闭连接,调用Disconnect(true)方法。

原文地址:https://www.cnblogs.com/pengze0902/p/8519715.html

时间: 2024-08-02 16:30:18

创建基于MailKit和MimeKit的.NET基础邮件服务的相关文章

基础邮件,mariadb数据库

postfix基础邮件服务 1.1 问题 本例要求在虚拟机server0上配置 postfix 基础服务,具体要求如下: 监听本机的所有接口 将邮件域和邮件服务主机名都改为 example.com 然后在server0上使用mail命令测试发信/收信操作: 由 root 给本机用户 mike 发一封测试邮件 查收用户 mike 的邮箱,读取邮件内容,确保是从 [email protected] 发过来的 1.2 方案 电子邮箱:[email protected]表示在互联网区域qq.com内的一

MailKit和MimeKit 收发邮件

新建项目,引用MailKit和MimeKit NuGet包 using CommonTool.MailKit; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProjectDemo.ConsoleApp { class Program { static void Main(string[] a

基于JAVA语言的selenium测试基础总结

目录一.基本语句 1.循环控制(break,continue) 3.字符的替换(replace,repalceFirst,replaceAll,regex) 4.字符串的连接("+",append) 5.字符串的截取和分割(substring,split) 6.文件夹的创建与删除(mkdirs,delete) 7.文件的读写(BufferedWrite,BufferedReader) 8.系统时间的获取( ((Calendar.getInstance()).get(Calendar.Y

Win10 IoT C#开发 2 - 创建基于XAML的UI程序 及 应用的三种部署方法

原文:Win10 IoT C#开发 2 - 创建基于XAML的UI程序 及 应用的三种部署方法 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我们讲了Raspberry安装Win10 IoT系统及搭建Visual Studio 2015开发环境的方法(http://www.cnblogs.com/cloudtech/p/5562120.html)

基于rpm包安装的httpd基础及基本配置

http:hyper text transfer protocol超文本传输协议 一.http简介 我们在浏览网页时,一定见过以html结尾的网页,这里html(hyper text mark language超文本标记语言)是一种编程语言,由html编写出来的文档即为超文本文档. 在早期,http只能传输超文本信息,而不能传输音视频等其他格式的文件,后来http协议中引入了MIME(mutipurpose Internet Mail Extesion)的机制,MIME可以将非文本文件编码成文本

Creating Dialogbased Win32 Application (4) / 创建基于对话框的Win32应用程序(四)Edit Control的应用、Unicode转ANSI、自动滚动 / Win32, VC++, Windows

创建基于对话框的Win32应用程序(四)——Edit Control的应用.Unicode转ANSI.自动滚动 之前的介绍中,我们用到了Button.Static Text.Checkbox这三个控件.这一节中我们将学习使用Edit Control(编辑框)控件,其中还包括Unicode转ANSI的方法.文本框自动滚动的功能等. 24.首先切换到Reasource View(Ctrl+Shift+E),找到待修改的主窗体,并从Toolbox(Ctrl+Atl+X)中添加Edit Control控

Creating Dialogbased Win32 Application (1) / 创建基于对话框的Win32应用程序(一)新建窗体 / Win32, VC++, Windows

创建基于对话框的Win32应用程序(一) —— 新建窗体 1.新建一个Visual C++的Empty Project.  2.在Solution Explorer中右键Add New Item,添加 .cpp 文件,并提供Win32应用程序的入口点函数.  3.在Solution Explorer或 Resources View 中右键Add Resource,选择Dialog.并在修改相关内容. 4.切换到 .cpp文件中,创建回调函数(Dlg_Proc),并在入口点函数中调用DialogB

js:对象的创建(基于组合和动态原型)

基于原型的创建虽然可以有效地完成封装,但是依然存在如下问题: 1.无法通过构造函数来设置属性值 2.当属性中有引用类型变量时,可能存在变量值重复 function Person(){ } Person.prototype = { constructor:Person, name:"Leon", age:30, friends:["Ada","Chris"], say:function(){ alert(this.name+"["

如何使用IntelliJ IDEA 14创建基于Maven3的Java Web Project

结合其他博主的一些文章,本文介绍了使用IntelliJ IDEA 14创建基于Maven3的Java Web Project 的步骤.同时也介绍了可能出现的错误以及解决方案. 环境介绍: 系统:OS X Yosemite (10.10.5) IDE :IntelliJ IDEA 14.1.4 Java :Oracle Java 1.8.0_51 Maven:3.3.3 创建步骤: 创建项目:Create New Project —> 设置SDK, 选择Maven, create from arc