这周做一个小功能,把服务异常信息已邮件和短信的形式发送给当事人,遇到不少问题。
这两个小功能的代码都是从别处拷贝过来的,放到我新建的项目中,开始的时候我心里都打鼓,因为拷贝别人的代码运行起来都不会很顺利,这个一般都有这个常识。果然,发邮件到时候那个服务器地址是错误的,不知道在别人的机器上是怎么调试通过的,先看看代码。
下面是发送邮件的类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Mail; using System.Net; namespace Assist.Assist { /// <summary> /// 发送Email /// </summary> public class MailSender { /// <summary> /// 邮件类实例 /// </summary> private SmtpClient serverHost; /// <summary> /// 发送Email构造方法 /// </summary> /// <param name="SmtpServer">SMTP 事务的主机的名称或 IP 地址</param> /// <param name="port">大于 0 的 System.Int32,包含要在 host 上使用的端口</param> /// <param name="isAuthentication">是否需要验证身份</param> /// <param name="userName">用户名</param> /// <param name="pwd">密码</param> public MailSender(string SmtpServer,int port,bool isAuthentication,string userName,string pwd) { if (port > 0) { serverHost = new SmtpClient(SmtpServer,port); } else { serverHost = new SmtpClient(SmtpServer); } if (isAuthentication) { serverHost.Credentials = new NetworkCredential(userName, pwd); } serverHost.EnableSsl = false; } /// <summary> /// 发送邮件 /// </summary> /// <param name="sender">发送邮箱</param> /// <param name="tos">接收邮箱</param> /// <param name="ccs">抄送邮箱</param> /// <param name="subject">主题</param> /// <param name="body">主题</param> /// <param name="isBodyHtml">邮件正文是否为 Html 格式</param> /// <param name="encoding">编码</param> /// <param name="files">附件</param> public void Send(string sender,string[] tos,string[] ccs,string subject, string body, bool isBodyHtml, Encoding encoding, params string[] files) { try { MailMessage message = new MailMessage(); foreach (string to in tos) { message.To.Add(to); } foreach (string cc in ccs) { message.CC.Add(cc); } message.Sender =new MailAddress(sender); message.From = new MailAddress(sender); message.IsBodyHtml = isBodyHtml; message.SubjectEncoding = encoding; message.BodyEncoding = encoding; message.Subject = subject; message.Body = body; message.Attachments.Clear(); if (files != null && files.Length != 0) { for (int i = 0; i < files.Length; ++i) { Attachment attach = new Attachment(files[i]); message.Attachments.Add(attach); } } serverHost.Send(message); } catch (Exception ex) { throw ex; } } } }
调用这个类当中的发邮件方法如下:
/// <summary> /// 发送设置,包括邮件和短信 /// </summary> static HostSettings settings = new HostSettings(); /// <summary> /// 发送邮件 /// </summary> public void SendEmail(string messageDetail) { MailSender mailClient = new MailSender(settings.SmtpServer, int.Parse(settings.SmtpPort), true, settings.UserName, settings.Password); mailClient.Send(settings.SendAddress, settings.To, settings.Cc, settings.Subject, messageDetail, true, Encoding.Default, null); }
这里面用到一个邮件服务器的配置类HostSettings,这个类全部是从配置文件中取得的配置项,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Configuration; namespace Model { /// <summary> /// 主机配置 /// </summary> public class HostSettings { /// <summary> /// ceair.com邮箱服务器地址 /// </summary> public string SmtpServer { get { return ConfigurationManager.AppSettings["smtpserver"]; } } /// <summary> /// 服务器端口 /// </summary> public string SmtpPort { get { return ConfigurationManager.AppSettings["smtpport"]; } } /// <summary> /// 邮箱用户名,就是邮箱地址不带.ceair.com /// </summary> public string UserName { get { return ConfigurationManager.AppSettings["username"]; } } /// <summary> /// 邮箱密码 /// </summary> public string Password { get { return ConfigurationManager.AppSettings["pwd"]; } } /// <summary> /// 发送人,就是邮箱用户名 /// </summary> public string SendAddress { get { return ConfigurationManager.AppSettings["sendaddress"]; } } /// <summary> /// 邮件主题 /// </summary> public string Subject { get { return ConfigurationManager.AppSettings["subject"]; } } /// <summary> /// 邮件接收人 /// </summary> public string[] To { get{ return ConfigurationManager.AppSettings["to"].Split(new char[] { ';' }); } } /// <summary> /// 邮件抄送人 /// </summary> public string[] Cc { get { return ConfigurationManager.AppSettings["cc"].Split(new char[] { ';' }); } } /// <summary> /// /// </summary> public string SmsServer { get { return ConfigurationManager.AppSettings["smsserver"]; } } /// <summary> /// / /// </summary> public string[] SendNumber { get { return ConfigurationManager.AppSettings["sendnumber"].Split(new char[] { ';' }); } } /// <summary> /// /// </summary> public bool EnableMail { get { return Convert.ToBoolean(ConfigurationManager.AppSettings["enablemail"]); } } /// <summary> /// /// </summary> public bool EnableSMS { get { return Convert.ToBoolean(ConfigurationManager.AppSettings["enablesms"]); } } } }
由于配置文件中有很多的敏感信息,就不贴出来了,从别处拷贝过来的邮箱帐号密码不真确,我调试的时候总是报错,如下:
SMTP 服务器要求安全连接或客户端未通过身份验证。 服务器响应为: Authentication required , 这个信息就是告诉我们登录服务器的帐号密码不正确。我这里是用自己公司的邮箱服务器,好像不用设置端口号,这里端口号没有配置。
发送短信的时候也不是很顺利,这里调用的一个webservice,引用service的方法是选中项目右击项目 -> 添加服务引用 -> 高级 -> 添加Web引用 -> 在URL文本框中输入服务地址即可,调用方法如下:
/// <summary> /// 发送短信 /// </summary> public void SendSms(string messageDetail) { //直接调用服务 //ServiceLogic.WebReference.SmsSenderServiceImplService smsClient = new ServiceLogic.WebReference.SmsSenderServiceImplService(); //使用服务类 SmsSenderServiceImplService smsClient = new SmsSenderServiceImplService(); string GroupSn = DateTime.Now.ToString("yyMMddhhmmssfff"); smsClient.sendSms(1001, string.Empty, settings.SendNumber, messageDetail, 3, Convert.ToInt64(GroupSn)); }
调试的时候执行SmsSenderServiceImplService smsClient = new SmsSenderServiceImplService();
这一句一直报下面的错误:未能加载文件或程序集“ServiceLogic.XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。系统找不到指定的文件。
我在网上搜了很多,貌似没有一个正确的,后面发现一个地方提到Visual Studio的配置
http://stackoverflow.com/questions/1127431/xmlserializer-giving-filenotfoundexception-at-constructor
Believe it or not, this is normal behaviour. An exception is thrown but handled by the XmlSerializer, so if you just ignore it everything should continue on fine.
信不信由你,这个是.net一个很常见的行为,这是一个由XmlSerializer抛出的异常,所以如果你忽略它也没有问题。
I have found this very anoying, and there have been many complaints about this if you search around a bit, but from what I've read Microsoft don't plan on doing anything about it.
我发现这个问题很烦人,如果你在网上搜索也会发现很多人遇到并抱怨这个,但是依我所见微软没有打算为此做任何事情。
You can avoid getting Exception popups all the time while debugging if you switch off first chance exceptions for that specific exception. In Visual Studio, go to Debug -> Exceptions (or press Ctrl + Alt + E), Common Language Runtime Exceptions -> System.IO -> System.IO.FileNotFoundException.
如果你在Visual Studio上做一些设置可以避免遇到弹出这个异常,在Visual Studio菜单中找调试—>异常(或者使用快捷键Ctrl + E + D)找到Common Language Runtime Exceptions -> System.IO -> System.IO.FileNotFoundException,并取消选中就不会看到了。
You can find information about another way around it in the blog post C# XmlSerializer FileNotFound exception (Chris Sells' tool XmlSerializerPreCompiler).
在这篇文章中你可以找到和这个问题相关的信息C# XmlSerializer FileNotFound exception。
而我把整个都选中了,如下图
作者:Tyler Ning
出处:http://www.cnblogs.com/tylerdonet/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过以下邮箱地址williamningdong@gmail.com 联系我,非常感谢。