我想在抛出异常时给自己发送一封电子邮件。使用 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;
}
谢谢大家。
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
。它对入口点有相同的限制,并且它返回计算机上的源路径而不是程序集名称(这可能不太有用),但更容易知道它会工作(因为它会编译它,就像可选的一样)参数被编译进去),并且它允许内联:
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>" +
...
对于任何寻找 ASP.NET Core 兼容解决方案的人来说,以下内容应该可行;
System.Reflection.Assembly.GetEntryAssembly().GetName().Name
这应该足够了
string projectName = Assembly.GetCallingAssembly().GetName().Name;
编辑* 如果您从另一个程序集运行它,那么您应该使用 GetCallingAssembly 来代替。
反射是找出产品名称、公司名称版本等信息的最佳方式。
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();
你可以使用
HttpContext.Current.ApplicationInstance.GetType().Assembly.GetName().Name
如果返回
App_global.asax....
,请将其更改为
HttpContext.Current.ApplicationInstance.GetType().BaseType.Assembly.GetName().Name
如果您没有在 HTTP 请求中运行,则需要某种方法来获取
HttpContext
。
如果您处于网站项目(而不是 Web 应用程序)中,这将返回不同的结果。
您还可以使用
HttpRuntime.AppDomainAppPath
获取磁盘上到部署站点的物理路径;这将在任何地方都有效。
只是在这里添加我的答案。
对于那些在项目中使用多个 Dll 的人,正确答案是:
string projectName = Assembly.GetExecutingAssembly().FullName.Split(',')[0];