Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在HTML中格式化异常,以便在c中向系统管理员发送电子邮件_C# - Fatal编程技术网

C# 在HTML中格式化异常,以便在c中向系统管理员发送电子邮件

C# 在HTML中格式化异常,以便在c中向系统管理员发送电子邮件,c#,C#,我们的错误处理程序通过电子邮件发送SysAdmin异常。现在它们看起来像纯文本一样糟糕 有没有一种方法可以处理异常并将其格式化为好看的html,以便系统管理员可以更轻松地阅读它?我在考虑制作一个包含%message%标记的html文件。将html文件放在资源中,以便可以像字符串一样调用它。然后只使用字符串。替换%message%,error.message;然后发电子邮件。我在某个地方读到一个很好的解决方案。我会找到这篇文章并编辑我的答案 <pre> ... htmlencoded

我们的错误处理程序通过电子邮件发送SysAdmin异常。现在它们看起来像纯文本一样糟糕


有没有一种方法可以处理异常并将其格式化为好看的html,以便系统管理员可以更轻松地阅读它?

我在考虑制作一个包含%message%标记的html文件。将html文件放在资源中,以便可以像字符串一样调用它。然后只使用字符串。替换%message%,error.message;然后发电子邮件。我在某个地方读到一个很好的解决方案。我会找到这篇文章并编辑我的答案

<pre>
... htmlencoded output from Exception.ToString() goes here ...
</pre>
我修改了一些做类似事情的代码。看看这是否有帮助

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using ConsoleApplication2.Properties;

class Program
{
    public static void Main(string[] args)
    {
        try
        {
            //throw an DivideByZeroException
            var a=0;
            var b=1/a;
        }
        catch (Exception ex)
        {
            //using the ExceptionXElement class
            var xmlException = new ExceptionXElement(ex);
            XslCompiledTransform myXslTrans = new XslCompiledTransform();

            //Resources.formatter is the xsl file added as a Resource to the project (ConsoleApplication2.Properties.Resources.formatter)
            //So, here we load the xsl
            myXslTrans.Load(XmlReader.Create(new StringReader(Resources.formatter)));

            //initialize a TextWriter, in this case a StringWriter and set it to write to a StringBuilder
            StringBuilder stringBuilder = new StringBuilder();
            XmlTextWriter myWriter = new XmlTextWriter(new StringWriter(stringBuilder));

            //apply the XSL transformations to the xmlException and output them to the XmlWriter
            myXslTrans.Transform(xmlException.CreateReader(), null, myWriter);

            //outputting to the console the HTML exception (you can send it as the message body of an email)
            Console.WriteLine(stringBuilder);
        }
    }
}

我将把异常序列化为XML元素,然后用自定义XSLT格式化它

关于如何序列化异常,有一种有趣的方法,您可以在此处阅读:。总而言之,如果您尝试用[Serializable]属性修饰从System.Exception继承的自定义类,然后在其上使用该类,则会因为实现System.Collections.IDictionary的属性而出现运行时异常。因此,您可以轻松地使用从.NET3.5开始的新API

下面是一个简单的程序,它生成一个异常并将其格式化为HTML

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" encoding="utf-8" indent="no"/>
  <xsl:template match="/">
    <html>
      <body>
        <h1>
          <xsl:value-of select="name(/*)"/>
        </h1>
        <h2>
          <xsl:value-of select="//Message"/>
        </h2>
        <table border="1">
          <tr bgcolor="#9acd32">
            <th>StackTrace</th>
          </tr>
          <xsl:for-each select="//Frame">
            <tr>
              <td>
                <xsl:value-of select="."/>
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
这是Formatter.xsl

下面是ExceptionXElement类定义:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" encoding="utf-8" indent="no"/>
  <xsl:template match="/">
    <html>
      <body>
        <h1>
          <xsl:value-of select="name(/*)"/>
        </h1>
        <h2>
          <xsl:value-of select="//Message"/>
        </h2>
        <table border="1">
          <tr bgcolor="#9acd32">
            <th>StackTrace</th>
          </tr>
          <xsl:for-each select="//Frame">
            <tr>
              <td>
                <xsl:value-of select="."/>
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
using System;
using System.Collections;
using System.Linq;
using System.Xml.Linq;

/// <summary>Represent an Exception as XML data.</summary>
public class ExceptionXElement : XElement
{
    /// <summary>Create an instance of ExceptionXElement.</summary>
    /// <param name="exception">The Exception to serialize.</param>
    public ExceptionXElement(Exception exception)
        : this(exception, false)
    { }

    /// <summary>Create an instance of ExceptionXElement.</summary>
    /// <param name="exception">The Exception to serialize.</param>
    /// <param name="omitStackTrace">
    /// Whether or not to serialize the Exception.StackTrace member
    /// if it's not null.
    /// </param>
    public ExceptionXElement(Exception exception, bool omitStackTrace)
        : base(new Func<XElement>(() =>
        {
            // Validate arguments

            if (exception == null)
            {
                throw new ArgumentNullException("exception");
            }

            // The root element is the Exception's type

            XElement root = new XElement
                (exception.GetType().ToString());

            if (exception.Message != null)
            {
                root.Add(new XElement("Message", exception.Message));
            }

            // StackTrace can be null, e.g.:
            // new ExceptionAsXml(new Exception())

            if (!omitStackTrace && exception.StackTrace != null)
            {
                root.Add
                (
                    new XElement("StackTrace",
                        from frame in exception.StackTrace.Split('\n')
                        let prettierFrame = frame.Substring(6).Trim()
                        select new XElement("Frame", prettierFrame))
                );
            }

            // Data is never null; it's empty if there is no data

            if (exception.Data.Count > 0)
            {
                root.Add
                (
                    new XElement("Data",
                        from entry in
                            exception.Data.Cast<DictionaryEntry>()
                        let key = entry.Key.ToString()
                        let value = (entry.Value == null) ?
                            "null" : entry.Value.ToString()
                        select new XElement(key, value))
                );
            }

            // Add the InnerException if it exists

            if (exception.InnerException != null)
            {
                root.Add
                (
                    new ExceptionXElement
                        (exception.InnerException, omitStackTrace)
                );
            }

            return root;
        })())
    { }
}