30

当抛出异常时,我想给自己发送一封电子邮件。使用 StackFrame 对象,我可以获得抛出异常的文件名、类名甚至类方法,但我还需要知道项目名称,因为我的许多 ASP.NET 项目具有相同的文件名、类名和方法.

这是我的代码:

    public static string JndGetEmailTextForDebuggingExceptionError(this Exception Ex)
    {
        StackFrame sf = Ex.JndGetStackFrame();

        string OutputHTML =         "<i><b><u>For Developer Use Only: </u></b></i>"                                                 + "<br>" + 
                                                                                                                                      "<br>" +
                                    "Project Name:   "  + HttpContext.Current.ApplicationInstance.GetType().Assembly.GetName().Name + "<br>" + //Under discussion
                                    "File Name:      "  + sf.GetFileName()                                                          + "<br>" +
                                    "Class Name:     "  + sf.GetMethod().DeclaringType                                              + "<br>" +
                                    "Method Name:    "  + sf.GetMethod()                                                            + "<br>" +
                                    "Line Number:    "  + sf.GetFileLineNumber()                                                    + "<br>" +
                                    "Line Column:    "  + sf.GetFileColumnNumber()                                                  + "<br>" +
                                    "Error Message:  "  + Ex.Message                                                                + "<br>" +
                                    "Inner Message : "  + Ex.InnerException.Message                                                 + "<br>";

        return OutputHTML;
    }

谢谢大家。

4

5 回答 5

36

如果您将日志记录代码放在单独的库程序集中,则可以使用Assembly.GetCallingAssembly,并直接从您的 ASP.NET 程序集调用到您的库,并标记该方法以使其不会被内联:

[MethodImpl(MethodImplOptions.NoInlining)]
public static string JndGetEmailTextForDebuggingExceptionError(this Exception Ex)
{
    StackFrame sf = Ex.JndGetStackFrame();

    string OutputHTML =         "<i><b><u>For Developer Use Only: </u></b></i>"                    + "<br>" + 
                                                                                                     "<br>" +
                                "Project Name:   "  + Assembly.GetCallingAssembly().GetName().Name + "<br>" +
                                "File Name:      "  + sf.GetFileName()                             + "<br>" +
                                "Class Name:     "  + sf.GetMethod().DeclaringType                 + "<br>" +
                                "Method Name:    "  + sf.GetMethod()                               + "<br>" +
                                "Line Number:    "  + sf.GetFileLineNumber()                       + "<br>" +
                                "Line Column:    "  + sf.GetFileColumnNumber()                     + "<br>" +
                                "Error Message:  "  + Ex.Message                                   + "<br>" +
                                "Inner Message : "  + Ex.InnerException.Message                    + "<br>";

    return OutputHTML;
}

在库中可能最终想要记录项目名称的任何入口点上,您必须记录调用程序集并标记它NoInlining,然后在内部传递它。

如果您使用的是 .NET 4.5,还有另一种方法可以做到这一点:CallerFilePath. 它对入口点有相同的限制,它返回你机器上的源路径而不是程序集名称(这可能不太有用),但更容易知道它会工作(因为它编译它,就像 optional参数被编译),它允许内联:

public static string JndGetEmailTextForDebuggingExceptionError
              (this Exception Ex, [CallerFilePath] string filePath = "")
{
    StackFrame sf = Ex.JndGetStackFrame();

    string OutputHTML =         "<i><b><u>For Developer Use Only: </u></b></i>" + "<br><br>" +
                                "Source File Path:   "  + filePath + "<br>" +
...
于 2013-08-19T15:07:09.240 回答
32

对于任何寻找 ASP.NET Core 兼容解决方案的人来说,以下应该可以工作;

System.Reflection.Assembly.GetEntryAssembly().GetName().Name


.NET Core API 参考

于 2016-09-27T07:16:00.413 回答
11

这应该足够了

string projectName = Assembly.GetCallingAssembly().GetName().Name;

编辑* 如果您从另一个程序集运行它,那么您应该改用GetCallingAssembly

于 2013-08-19T14:48:46.270 回答
5

您可以使用

HttpContext.Current.ApplicationInstance.GetType().Assembly.GetName().Name

如果返回App_global.asax....,请将其更改为

HttpContext.Current.ApplicationInstance.GetType().BaseType.Assembly.GetName().Name

如果您没有在 HTTP 请求中运行,您将需要一些方法来获取HttpContext.

如果您在网站项目中(与 Web 应用程序相反),这将返回不同的结果。

您还可以使用HttpRuntime.AppDomainAppPath获取磁盘上到已部署站点的物理路径;这将在任何地方工作。

于 2013-08-19T14:47:14.953 回答
5

反思是找出产品名称、公司名称版本等信息的最佳方式。

public static string ProductName
{
 get
 {
    AssemblyProductAttribute myProduct =(AssemblyProductAttribute)AssemblyProductAttribute.GetCustomAttribute(Assembly.GetExecutingAssembly(),
     typeof(AssemblyProductAttribute));
      return myProduct.Product;
  }
}

还有另一种方式,比如直接获取项目名称

string projectName=System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString();
于 2013-08-19T14:48:08.377 回答