如何从方法内部访问属性数据

时间:2018-06-27 18:27:23

标签: postsharp

我有一个这样的PostSharp类:

[Serializable] 
public sealed class TraceAspect : OnMethodBoundaryAspect
{ 
    public override void OnException(MethodExecutionArgs args) 
    { 
        public Dictionary<string, object> tt 
             = new Dictionary<string, object>();

        tt.Add("WebServiceName", args.Method.DeclaringType.Namespace); 

        for (int x = 0; x < args.Arguments.Count; x++) 
        { 
           // ignore ref parameters 
           if (!args.Method.GetParameters()[x].ParameterType.IsByRef) 
               tt.Add(args.Method.GetParameters()[x].Name, args.Arguments.GetArgument(x)); 
        }

        // call to my custom logging with parameter name and values in tt
        // …

        args.FlowBehavior = FlowBehavior.Continue;

        base.OnException(args); 
     } 
}

这是我的代码在Web服务中以这种方式使用的:

[WebMethod,Trace] 
public int TestFunction(string Param1, string Param2, string ref error) 
{ 
    try
    {
        bool test = true;
        if (test)
        {
             error =  "this is a test exction";

             throw new Exception (error);
        }

        return 1;
     }
     catch (Exception ex)
     {
         error = ex.Message;

         throw ex;
     }

     return 2;
}

我的问题是我的测试方法从不返回2。该怎么办?

致谢

1 个答案:

答案 0 :(得分:0)

为了更好地理解此问题,您可以直观地了解如何将OnException方面编织到方法的代码中。它基本上将整个方法主体包装到try-catch块中。因此,结果类似于以下内容:

[WebMethod,Trace] 
public int TestFunction(string Param1, string Param2, string ref error) 
{ 
    try
    {
        try
        {
            bool test = true;
            if (test)
            {
                 error =  "this is a test exction";

                 throw new Exception (error);
            }

            return 1;
        }
        catch (Exception ex)
        {
            error = ex.Message;

            throw ex;
        }

        return 2;
    }
    catch (Exception e)
    {
        // Call to TraceAspect.OnException
    }
    // The execution will continue here
}

如您所见,异常在第一个catch中被捕获并重新抛出。之后,它再次被第二个catch捕获。此时return 2;语句已被跳过。

只要将args.ReturnValue设置为args.FlowBehaviorContinue,就可以通过设置Return来设置方面中方法的新返回值(这两个值在异常流行为的情况,请参见FlowBehavior Enumeration)。

例如:

[Serializable] 
public sealed class TraceAspect : OnMethodBoundaryAspect
{ 
    private object returnValue;

    public TraceAspect(object returnValue)
    {
        this.returnValue = returnValue;
    }

    public override void OnException(MethodExecutionArgs args) 
    { 
        public Dictionary<string, object> tt 
             = new Dictionary<string, object>();

        tt.Add("WebServiceName", args.Method.DeclaringType.Namespace); 

        for (int x = 0; x < args.Arguments.Count; x++) 
        { 
           // ignore ref parameters 
           if (!args.Method.GetParameters()[x].ParameterType.IsByRef) 
               tt.Add(args.Method.GetParameters()[x].Name, args.Arguments.GetArgument(x)); 
        }

        // call to my custom logging with parameter name and values in tt
        // …

        args.FlowBehavior = FlowBehavior.Continue;
        args.ReturnValue = this.returnValue;

        base.OnException(args); 
     } 
}