I want to send an email to myself when an exception is thrown. Using StackFrame object, I am able to get File Name, Class Name and even class method that throw the Exception, but I also need to know the project name as many of my ASP.NET project has the same file name, class name and method.
当出现异常时,我想给自己发一封邮件。使用StackFrame对象,我可以获得抛出异常的文件名、类名,甚至类方法,但我还需要知道项目名,就像我的许多ASP一样。NET项目具有相同的文件名、类名和方法。
This is my code:
这是我的代码:
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;
}
Thanks ALL.
谢谢所有。
5 个解决方案
#1
13
You can use Assembly.GetCallingAssembly
if you have your logging code in a separate library assembly, and call directly from your ASP.NET assembly to your library, and you mark the method so that it won't be inlined:
您可以使用组装。如果您在一个单独的库程序集中有日志代码,并且直接从ASP调用,那么GetCallingAssembly。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;
}
On any entry points in your library that can end up wanting to log the project name, you'd have to record the calling assembly and mark it NoInlining
, then pass that around internally.
在库中任何可能最终要记录项目名称的入口点上,您都必须记录调用程序集并标记为NoInlining,然后在内部传递它。
If you're using .NET 4.5, there's an alternative way to do this: CallerFilePath
. It has the same restrictions on entry points, and it returns the source path on your machine instead of the assembly name (which is probably less useful), but it's easier to know that it'll work (because it compiles it, just like optional parameters are compiled in), and it allows inlining:
如果您正在使用。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>" +
...
#2
10
For anyone looking for an ASP.NET Core compatible solution, the following should work;
对于任何寻找ASP的人。NET核心兼容解决方案,以下应能工作;
System.Reflection.Assembly.GetEntryAssembly().GetName().Name
net核心API参考
#3
5
You can use
您可以使用
HttpContext.Current.ApplicationInstance.GetType().Assembly.GetName().Name
If this returns App_global.asax....
, change it to
如果这个回报App_global.asax ....改变它,
HttpContext.Current.ApplicationInstance.GetType().BaseType.Assembly.GetName().Name
If you aren't running in an HTTP request, you will need some way to get ahold of the HttpContext
.
如果您没有在HTTP请求中运行,则需要一些方法来获得HttpContext。
This will return different results if you're in a Web Site project (as opposed to Web Application).
如果您在Web站点项目中(与Web应用程序相反),这将返回不同的结果。
You can also use HttpRuntime.AppDomainAppPath
to get the physical path on disk to the deployed site; this will work everywhere.
还可以使用HttpRuntime。appdomainapath获取磁盘上到部署站点的物理路径;这将工作无处不在。
#4
4
Reflection is the best way to find out product name,company name version like information.
反射是找出产品名称、公司名称等信息的最好方法。
public static string ProductName
{
get
{
AssemblyProductAttribute myProduct =(AssemblyProductAttribute)AssemblyProductAttribute.GetCustomAttribute(Assembly.GetExecutingAssembly(),
typeof(AssemblyProductAttribute));
return myProduct.Product;
}
}
And Another way like get direct project name
另一种方法是直接获取项目名称
string projectName=System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString();
#5
2
This ought to be enough
这应该足够了
string projectName = Assembly.GetCallingAssembly().GetName().Name;
Edit* If you are running this from another assembly then you should use GetCallingAssembly instead.
如果您正在从另一个程序集运行这个程序,那么您应该使用GetCallingAssembly。
#1
13
You can use Assembly.GetCallingAssembly
if you have your logging code in a separate library assembly, and call directly from your ASP.NET assembly to your library, and you mark the method so that it won't be inlined:
您可以使用组装。如果您在一个单独的库程序集中有日志代码,并且直接从ASP调用,那么GetCallingAssembly。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;
}
On any entry points in your library that can end up wanting to log the project name, you'd have to record the calling assembly and mark it NoInlining
, then pass that around internally.
在库中任何可能最终要记录项目名称的入口点上,您都必须记录调用程序集并标记为NoInlining,然后在内部传递它。
If you're using .NET 4.5, there's an alternative way to do this: CallerFilePath
. It has the same restrictions on entry points, and it returns the source path on your machine instead of the assembly name (which is probably less useful), but it's easier to know that it'll work (because it compiles it, just like optional parameters are compiled in), and it allows inlining:
如果您正在使用。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>" +
...
#2
10
For anyone looking for an ASP.NET Core compatible solution, the following should work;
对于任何寻找ASP的人。NET核心兼容解决方案,以下应能工作;
System.Reflection.Assembly.GetEntryAssembly().GetName().Name
net核心API参考
#3
5
You can use
您可以使用
HttpContext.Current.ApplicationInstance.GetType().Assembly.GetName().Name
If this returns App_global.asax....
, change it to
如果这个回报App_global.asax ....改变它,
HttpContext.Current.ApplicationInstance.GetType().BaseType.Assembly.GetName().Name
If you aren't running in an HTTP request, you will need some way to get ahold of the HttpContext
.
如果您没有在HTTP请求中运行,则需要一些方法来获得HttpContext。
This will return different results if you're in a Web Site project (as opposed to Web Application).
如果您在Web站点项目中(与Web应用程序相反),这将返回不同的结果。
You can also use HttpRuntime.AppDomainAppPath
to get the physical path on disk to the deployed site; this will work everywhere.
还可以使用HttpRuntime。appdomainapath获取磁盘上到部署站点的物理路径;这将工作无处不在。
#4
4
Reflection is the best way to find out product name,company name version like information.
反射是找出产品名称、公司名称等信息的最好方法。
public static string ProductName
{
get
{
AssemblyProductAttribute myProduct =(AssemblyProductAttribute)AssemblyProductAttribute.GetCustomAttribute(Assembly.GetExecutingAssembly(),
typeof(AssemblyProductAttribute));
return myProduct.Product;
}
}
And Another way like get direct project name
另一种方法是直接获取项目名称
string projectName=System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString();
#5
2
This ought to be enough
这应该足够了
string projectName = Assembly.GetCallingAssembly().GetName().Name;
Edit* If you are running this from another assembly then you should use GetCallingAssembly instead.
如果您正在从另一个程序集运行这个程序,那么您应该使用GetCallingAssembly。