Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.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
Exception 如何编写捕获异常并删除stacktrace的属性?_Exception_C# 4.0_Stack Trace_Postsharp - Fatal编程技术网

Exception 如何编写捕获异常并删除stacktrace的属性?

Exception 如何编写捕获异常并删除stacktrace的属性?,exception,c#-4.0,stack-trace,postsharp,Exception,C# 4.0,Stack Trace,Postsharp,我希望为函数(或类)编写一个属性,该属性将捕获抛出的任何异常,并将其StackTrace属性设置为string.Empty。我该怎么做 编辑: 如果我不能在普通C#中实现这一点,那么如何使用PostSharp在C#中实现这一点 [Serializable] public class MyAspect: OnExceptionAspect { public override void OnException(MethodExecutionArgs args) {

我希望为函数(或类)编写一个属性,该属性将捕获抛出的任何异常,并将其
StackTrace
属性设置为
string.Empty
。我该怎么做

编辑:

如果我不能在普通C#中实现这一点,那么如何使用PostSharp在C#中实现这一点

[Serializable] 
public class MyAspect: OnExceptionAspect 
{
    public override void OnException(MethodExecutionArgs args)
    {
       throw new MyCustomException(args.Exception);
    }
} 


public class MyCustomException : Exception
{
    public override string StackTrace
    {
        get
        {
            //return new StackTrace(10).ToString(); //Skip frames
            return string.Empty; //Return empty string
        }
    }
}
实际上,您必须抛出一个新异常@Ani的示例将简单地重新显示已使用相同堆栈跟踪抛出的异常(这是相同的,因为您是如何到达方面的)。抛出新异常将“更改”堆栈跟踪,但不会擦除它。如果要删除它,则需要抛出覆盖堆栈跟踪属性的自己的类。将旧异常传递给新异常将使旧异常成为内部异常(如果需要)

您可以使用PostSharp或不使用PostSharp来完成此操作密钥是您的自定义异常类。

给定以下代码

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Test1();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.StackTrace + Environment.NewLine);
        }

        Console.ReadKey();
    }

    private static void Test1()
    {
        try
        {
            Test2();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.StackTrace + Environment.NewLine);
            throw e;
        }
    }

    private static void Test2()
    {
        try
        {
            Test3();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.StackTrace + Environment.NewLine);
            throw;
        }
    }

    [MyAspect]
    private static void Test3()
    {
        throw new InvalidOperationException();
    }
}

[Serializable]
public class MyAspect : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        throw args.Exception;
    }
}
输出是

在控制台Application 5.MyAspect.OneException(MethodExecutionArgs C:\T est\Program.cs中的args):第69行 C:\Test\Program.cs中的ConsoleApplication5.Program.Test3():第59行
在C:\Test\Program.cs中的ConsoleApplication5.Program.Test2()处:第47行

在控制台Application 5.MyAspect.OneException(MethodExecutionArgs C:\T est\Program.cs中的args):第69行 C:\Test\Program.cs中的ConsoleApplication5.Program.Test3():第59行
在C:\Test\Program.cs中的ConsoleApplication5.Program.Test2()处:第52行
在C:\Test\Program.cs中的ConsoleApplication5.Program.Test1()处:第34行

在C:\Test\Program.cs:行中的ConsoleApplication5.Program.Test1()处 39在控制台应用程序5.Program.Main(字符串[]args)中 C:\Test\Program.cs:第19行


异常的原始堆栈跟踪存储在
exception
类的字段中。如果要在不创建自己的异常类型的情况下删除它,可以通过反射将其删除,如下所示:

[Serializable] 
public sealed class NoStackTraceException : OnExceptionAspect 
{
    public override void OnException(MethodExecutionArgs args)
    {
       RemoveStackTrace(args.Exception);
    }

    private void RemoveStackTrace(Exception exception)
    {
        FieldInfo stackTraceField = typeof(Exception).GetField("_stackTrace",
             BindingFlags.NonPublic | BindingFlags.Instance);
        if (stackTraceField != null)
        {
            // sets the value of _stackTrace to null
            stackTraceField.SetValue(exception, null);
        }
    }
}
异常将不再包含堆栈跟踪


Edit当然,您也可以在不使用PostSharp的情况下完成同样的事情,只需在
catch
块中执行即可。

有没有一种方法可以在不使用自定义类的情况下执行此操作?例如,如果我想删除抛出的
系统.Exception
的堆栈跟踪,您可以使用反射,但实际上这不是您想在生产中执行的操作。我希望它是学术性的,或者只是为了测试。请参见@hmemcpy-answer。在Test1()方法中,为什么要使用“throw e;”而不是“throw;”?好奇:为什么要这样做?请参见下面我的答案,尽管我不鼓励这样做。异常的存在是有原因的,这是为了在发生异常时帮助调试。通过删除堆栈跟踪,可以有效地隐藏错误源,如果不进行调试,则无法找到错误源。如果出于某种原因担心隐私问题,您可以尝试对stacktrace进行模糊处理或加密(使用答案中描述的相同方法),以便稍后可以对其进行解密,比如从日志文件进行解密。这也是我需要的,原因是我需要将异常对象传递给Web服务,但由于某种原因,我无法让服务接受它。所以我可以传递消息和StackTrace,然后重新创建异常服务器端。