Log4net html 格式的 SmtpAppender

2023-11-22

我正在尝试以 HTML 格式向我发送电子邮件。

    <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">

  <to value="[email protected]"/>
  <from value="[email protected]"/>
  <subject value="zzzAdmin Logged Event" />
  <smtpHost value="email.zzz.com"/>
  <bufferSize value="1"/>
  <lossy value="false"/>
  <authentication value="Basic" />

我将错误记录为 html 格式的文本,但电子邮件客户端将 HTML 呈现为纯文本。

我如何告诉 SMTPAppender 将 HTML 类型添加到电子邮件消息中,以便客户端将消息呈现为 HTML 形式。


由于 log4net 到目前为止不支持消息正文中的 HTML 格式,因此我编写了自己的附加程序:

using System;
using System.Net.Mail;
using log4net.Appender;

namespace log4net.Appender
{
    public class ExtendedSmtpAppender : SmtpAppender
    {
        public bool IsBodyHtml { get; set; }

        protected override void SendEmail(string messageBody)
        {
            // .NET 2.0 has a new API for SMTP email System.Net.Mail
            // This API supports credentials and multiple hosts correctly.
            // The old API is deprecated.

            // Create and configure the smtp client
            SmtpClient smtpClient = new SmtpClient();
            if (!String.IsNullOrEmpty(SmtpHost))
            {
                smtpClient.Host = SmtpHost;
            }
            smtpClient.Port = Port;
            smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtpClient.EnableSsl = EnableSsl;

            if (Authentication == SmtpAuthentication.Basic)
            {
                // Perform basic authentication
                smtpClient.Credentials = new System.Net.NetworkCredential(Username, Password);
            }
            else if (Authentication == SmtpAuthentication.Ntlm)
            {
                // Perform integrated authentication (NTLM)
                smtpClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
            }

            using (MailMessage mailMessage = new MailMessage())
            {
                mailMessage.IsBodyHtml = IsBodyHtml;
                mailMessage.Body = messageBody;
                //mailMessage.BodyEncoding = BodyEncoding;
                mailMessage.From = new MailAddress(From);
                mailMessage.To.Add(To);
                if (!String.IsNullOrEmpty(Cc))
                {
                    mailMessage.CC.Add(Cc);
                }
                if (!String.IsNullOrEmpty(Bcc))
                {
                    mailMessage.Bcc.Add(Bcc);
                }
                if (!String.IsNullOrEmpty(ReplyTo))
                {
                    // .NET 4.0 warning CS0618: 'System.Net.Mail.MailMessage.ReplyTo' is obsolete:
                    // 'ReplyTo is obsoleted for this type.  Please use ReplyToList instead which can accept multiple addresses. http://go.microsoft.com/fwlink/?linkid=14202'
#if !FRAMEWORK_4_0_OR_ABOVE
                    mailMessage.ReplyTo = new MailAddress(ReplyTo);
#else
                    mailMessage.ReplyToList.Add(new MailAddress(m_replyTo));
#endif
                }
                mailMessage.Subject = Subject;
                //mailMessage.SubjectEncoding = m_subjectEncoding;
                mailMessage.Priority = Priority;

                // TODO: Consider using SendAsync to send the message without blocking. This would be a change in
                // behaviour compared to .NET 1.x. We would need a SendCompletedCallback to log errors.
                smtpClient.Send(mailMessage);
            }
        }
    }
}

要在 log4net 配置中使用此附加程序,只需替换标准 SmtpAppender 定义的命名空间和类名称,并添加 isBodyHtml 选项,如下所示:

<appender name="SmtpAppender" type="log4net.Appender.ExtendedSmtpAppender">
    ...
    <isBodyHtml value="true" />
    ...
</appender>

SendEmail 方法主体源取自最新版本的标准 log4net 的 SmtpAppender。我只删除了支持内容的旧框架版本并添加了以下字符串:

mailMessage.IsBodyHtml = IsBodyHtml;

您可以获得最新版本的标准 log4netSmtpAppender here.

UPDATE:
下面是一个示例配置(灵感来自these例子):

<log4net>
  <!-- SmtpExAppender is set to be our ExtendedSmtpAppender -->
  <appender name="SmtpExAppender" type="log4net.Appender.ExtendedSmtpAppender">
    <to value="[email protected]" />
    <from value="[email protected]" />
    <subject value="test logging message" />
    <isBodyHtml value="true" />
    <smtpHost value="SMTPServer.domain.com" />
    <bufferSize value="512" />
    <lossy value="true" />
    <evaluator type="log4net.Core.LevelEvaluator">
      <threshold value="WARN"/>
    </evaluator>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
    </layout>
  </appender>

  <!-- Set root logger level to DEBUG and its only appender to SmtpExAppender -->
  <root>
    <level value="DEBUG" />
    <appender-ref ref="SmtpExAppender" />
  </root>
</log4net>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Log4net html 格式的 SmtpAppender 的相关文章

  • 使用 Java 登录

    我通过执行以下代码在 java 中创建一个记录器 private static final String logFile File separator Log Files File separator Log Long toString S
  • 改变方法中的结构

    如何更改外部方法中的结构 public void ChangeStruct MyStruct myStruct myStruct field1 10 return 当我在该方法之后将结构传递给 ChangeStruct 方法时 我希望更改
  • 尝试使用 swift mailer、gmail smtp、php 发送邮件

    这是我的代码
  • Visual Studio 2022 - 编译旧应用程序时出错

    我们正在尝试在 Visual Studio 2022 中使用 VB6 32 位应用程序 编译 2002 年以来非常旧的应用程序 我们需要调试此应用程序并能够在 Windows 10 计算机上运行此应用程序 编译时 我们发现以下错误 这似乎是
  • 为什么我的 COM 对象不显示组件服务中的方法?

    我正在尝试创建一个 COM 对象并将其注册到 COM 下 一切似乎都很顺利 但是当我查看组件服务并深入了解时 控制台根目录 组件服务 电脑 我的电脑 COM 应用程序 测试通讯 组件 TestCom Com MyCom 接口 MyCom 方
  • 如何动态加载包含非托管代码的原始程序集?(绕过“无法验证的代码失败策略检查”异常)

    我将举一个使用的例子系统 Data SQLite DLL http sqlite phxsoftware com 这是一个包含非托管代码的混合程序集 如果我执行这个 var assembly Assembly LoadFrom System
  • StreamReader,C#,peek

    我有一个 StreamReader 它偶尔会检查它是否有更多内容可以从简单的文本文件中读取 它使用 peek 属性 问题是 当我使用 peek 时 位置发生了变化 尽管不应该发生 FileStream m fsReader new File
  • C# Julian 日期解析器

    我在电子表格中有一个单元格 它是 Excel 中的日期对象 但当它来自 C1 的 xls 类时 它会变成双精度型 类似于 2009 年 1 月 7 日的 39820 0 我读到这是儒略日期格式 有人可以告诉我如何在 C 中将其解析回 Dat
  • EasyNetQ 模型关闭

    我使用 EasyNetQ 实现了一个简单的 RabbitMQ 客户端 连接后 我收到一条通知 队列模型关闭 这是我的代码 var bus RabbitHutch CreateBus String Format host 0 hostName
  • 更换 I 过滤器

    我目前正在使用 IFilters 从各种文件 word excel tiff pdf 等 中提取文本 据我所知 IFilter 已在 Windows 8 中停止使用 是否有人对如何在不安装本机应用程序的情况下提取文本有任何建议 如果有什么用
  • 设置 Form.KeyPreview = true 的缺点?

    我想知道 Form KeyPreview 属性实际上有什么用处 它为什么存在以及将其设置为 true 会带来什么 风险 我想它一定有some负面影响 否则它根本不应该存在 或者至少默认情况下是正确的 EDIT 我很清楚what确实如此 我问
  • 如何记录 sqlalchemy 中返回的 SQL 语句和行以帮助调试?

    我该如何配置sqlalchemy记录它向数据库服务器发出的 SQL 语句 并记录从这些语句返回的行 这对于调试很有用 选项 1 设置sqlalchemy engine记录器日志级别为logging INFO or logging DEBUG
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • C# - 方法必须有返回类型

    我在调用 C 中的方法时遇到问题 不断收到消息 方法 计算 必须有返回类型 using System Diagnostics namespace WindowsFormsApplication1 public partial class F
  • 使用实体框架重叠约会

    我将 asp net mvc 与实体框架一起使用 我有一个包含 startat 字段 endat 字段和 roomid 字段 称为 SpaceConfigurationId 的约会列表 并且希望查找给定房间已重复预订的约会列表 可以假设 e
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org

随机推荐

  • 变分自动编码器:Keras 中的实现预热

    我最近读过这张纸它引入了一个称为 预热 WU 的过程 该过程包括将 KL 散度中的损失乘以一个变量 该变量的值取决于纪元数 从 0 到 1 线性演化 我想知道这是否是做到这一点的好方法 beta K variable value 0 0 d
  • 在第一次声明后将函数声明为默认函数

    In 8 4 2 Explicitly defaulted functions dcl fct def default 标准的 显式默认函数和隐式声明函数是 统称为默认函数 并且实现应 为它们提供隐式定义 12 1 12 4 12 8 这可
  • Azure Web Api - 每 4 分钟和 30 分钟等待一次 Sql 连接

    在 ApiController 上的请求中 我跟踪等待 Sql 连接打开的持续时间 await t TrackDependencyAsync async gt await sqlConnection OpenAsync return tru
  • PostgreSQL 日期范围未正确使用索引

    我有一个简单的表 其中有一个带有日期类型的 user birthday 字段 可以是 空值 CREATE TABLE users user id bigserial NOT NULL user email text NOT NULL use
  • org.springframework.context.ConfigurableApplicationContext 类型无法解析

    当我尝试在 Spring Tool Suite 中创建第一个应用程序时 出现以下错误 该行有多个标记 org springframework context ConfigurableApplicationContext 类型无法解析 这是
  • Rails:从列中选择唯一值

    我已经有了一个可行的解决方案 但我真的很想知道为什么这不起作用 ratings Model select rating uniq ratings each r puts r rating 它选择但不打印唯一值 而是打印所有值 包括重复项 它
  • 我可以在 C++ 中创建一个新运算符吗?如何创建?

    MATLAB 数组支持矩阵运算和元素运算 例如 M N and M N 这是区分两种不同操作的非常直观的方法 如果我想在C 中实现类似的操作 我该怎么做 我可以创建一个新的运算符吗 也 如果是 有人可以给我一些指导吗 不 你不能超载op C
  • 如何从 if 语句中获取类模板的实例? (C++)

    假设我有一个类模板 其中有一个成员pData 这是一个AxB任意类型的数组T template
  • 是否可以将喷气背包中的一排边缘倒圆?

    这就是我想要实现的目标 因此 我连续创建了 2 个圆形按钮 并根据是否选择它们提供了不同的背景颜色 目标是创建一种选项卡 切换的错觉 未选中的按钮将具有与该行的背景颜色相同的颜色 不幸的是 由于行是矩形形状 因此在拐角处有残留空间 仍然显示
  • 抑制整个脚本的错误

    我想抑制 VBS 登录脚本中可能出现的所有错误 我可以用以下内容包围整个 500 行脚本吗 On Error Resume Next whole script 500 lines of code On Error GoTo 0 You ca
  • 角度过滤器按字符匹配?

    我有角度 1 3 并且有以下数组 data id 2 name danny davids age 9 id 3 name sanny gordon age 9 我希望过滤器执行以下操作 当我开始写 s 这个词时 我希望 danny davi
  • 流 - 按属性和最大值收集

    问题陈述 给定以下课程 针对问题进行了简化 public static class Match private final String type private final int score public Match String ty
  • 如何在android中获取浏览器历史记录?

    我想实现一个应用程序来获取android默认浏览器历史记录并将浏览器历史记录保存到xml文件中 但是浏览器历史记录在某些设备中没有保存到xml文件中 我已经实现了我的应用程序来获取浏览器历史记录信息以保存到 xml 文件 如下所示 priv
  • 使用表单更新谷歌电子表格上的现有数据?

    我想建立一种自动系统来更新锦标赛的一些比赛结果 我有一个自动电子表格 显示了所有结果 但更新所有结果需要花费很多时间 所以我想知道是否可以制作一个表格以便更轻松地更新它们 在表格中 我将输入车手姓名和他在比赛中赢得的积分 锦标赛每月有 4
  • Python 中的递归生成器

    我编写了一个函数来返回一个生成器 其中包含给定长度的子字符串的每个唯一组合 这些子字符串包含主字符串中的 n 个以上元素 举例来说 如果我有 abcdefghi 和长度为 2 的探针 并且每个列表有 4 个元素的阈值 我想得到 ab cd
  • 捕获所有 JavaScript 错误并将其发送到服务器 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 Locked 这个问题及其答案是locked因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 我想知道是否有人有在全局范围内处理 JavaScript 错误并将其
  • Django 中两个模型之间的多对多关系

    我正在尝试建立一个网站 用户可以添加他们正在学习的课程 我想知道应该如何添加ManyToMany关系 这样我们就可以根据课程代码或讲师或任何字段获取课程中的所有用户 我们还可以获取用户注册的课程 目前 我的数据库结构是 class Cour
  • 不同型号手机上的布局

    最近我为 Galaxy 10 1 7 英寸 1024x600 480x800 Note 800 高度和 S3 720 高度开发了一个应用程序 它们都在这些分辨率上完美运行 但当我们谈论 Note 2 和 Galaxy 7 Plus 等设备时
  • 使用python从列表中随机提取x个项目

    从两个列表开始 例如 lstOne 1 2 3 4 5 6 7 8 9 10 lstTwo 1 2 3 4 5 6 7 8 9 10 我想让用户输入他们想要提取的项目数量 占整个列表长度的百分比 以及从每个列表中随机提取的相同索引 例如 假
  • Log4net html 格式的 SmtpAppender

    我正在尝试以 HTML 格式向我发送电子邮件