c#中Attribute如何实现参数的拦截

by_封爱 版主 2019-09-04 05:29:30
背景: 不是mvc 不是webapi. 就普通的方法..


public void add(int i)
{
//输出i
}


我想拦截一下这个方法的参数,也就是给参数加属性.


public class myAttribute:Attribute
{

}


然后

public void add([myAttribute]int i)


可以理解成webapi中的FromBody那种东西吧.

现在就是在myAttribute里写点什么 能获取到int 这个类型 以及i 这个变量 以及输出i*100 3个方法呢.


因为我实现的大概是这样..

public class myAttribute:Attribute
{
var body=request["body"];
var obj=反序列化<user>(body);
return obj
}
public void add([myAttribute]userinfo body)


其中我就是需要userinfo这个类型,body这个参数.以及返回值.



...全文
1156 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
一个武术猴子 2019-10-18
  • 打赏
  • 举报
回复
引用 20 楼 by_封爱 的回复:
[quote=引用 19 楼 bloodish 的回复:] 形式有区别,效果一致,不需要纠结.
是个好东西... 就是收费 破解的好像也不仅仅是DLL.一台机器还得破一次.. 我太难了.[/quote] 学到了。
一个武术猴子 2019-09-10
  • 打赏
  • 举报
回复
每太看明白可能 能力不够,,, 我以前方法体 上面的限制。我都是 where T: 实体名字。。等等,通过 where 来进行 参数的 规定 定义
by_封爱 版主 2019-09-10
  • 打赏
  • 举报
回复
引用 19 楼 bloodish 的回复:
形式有区别,效果一致,不需要纠结.
是个好东西... 就是收费 破解的好像也不仅仅是DLL.一台机器还得破一次.. 我太难了.
bloodish 2019-09-10
  • 打赏
  • 举报
回复
形式有区别,效果一致,不需要纠结.
  • 打赏
  • 举报
回复
引用 16 楼 by_封爱 的回复:
[quote=引用 15 楼 bloodish 的回复:] 按你的需求,可以参考: how-to-modify-method-arguments-using-postsharp
这代码看起来 好像是可以.. 但是我给参数加特性 的时候 报错了.

public class AAA : MethodInterceptionAspect
    {
        public override void OnInvoke(MethodInterceptionArgs args)
        {
            Console.WriteLine(args);
            args.Arguments.SetArgument(0, "456");
            args.Proceed();
        }
    }
我只要继承了postsharp里的东西.. 我给参数加特性

public void add([AAA]int i)
        {
            Console.WriteLine(i);
        }
就提示我 Cannot apply the custom attribute "LocalSQLManager.AAA" on the i : int32 "LocalSQLManager.Form1.add(System.Int32)": cannot apply this custom attribute on a i : int32. Valid targets are: Parameter. [/quote] 应该是这么用的吧

        [AAA]
        public void add(int i)
        {
            Console.WriteLine(i);
        }
by_封爱 版主 2019-09-10
  • 打赏
  • 举报
回复
我看到的代码都是给方法加特性,没有给参数加特性的... 我现在只想在参数上面加.... 好像实现不了..
by_封爱 版主 2019-09-10
  • 打赏
  • 举报
回复
引用 15 楼 bloodish 的回复:
按你的需求,可以参考: how-to-modify-method-arguments-using-postsharp
这代码看起来 好像是可以.. 但是我给参数加特性 的时候 报错了.

public class AAA : MethodInterceptionAspect
    {
        public override void OnInvoke(MethodInterceptionArgs args)
        {
            Console.WriteLine(args);
            args.Arguments.SetArgument(0, "456");
            args.Proceed();
        }
    }
我只要继承了postsharp里的东西.. 我给参数加特性

public void add([AAA]int i)
        {
            Console.WriteLine(i);
        }
就提示我 Cannot apply the custom attribute "LocalSQLManager.AAA" on the i : int32 "LocalSQLManager.Form1.add(System.Int32)": cannot apply this custom attribute on a i : int32. Valid targets are: Parameter.
bloodish 2019-09-10
  • 打赏
  • 举报
回复
按你的需求,可以参考: how-to-modify-method-arguments-using-postsharp
wanghui0380 2019-09-10
  • 打赏
  • 举报
回复
理解一下下面这个 xxxx([notNull]xxxx) 这个东西就是 有关这类东西的搞法,用postsharp搞是这样的 http://badecho.com/2011/11/validating-method-parameters-with-postsharp/ 已经数了,这个东西在nuget上的代码里,7成的最近项目都在使用,当然他们是引用的一个库,但是这个库呢,实际使用的就是静态IL织入的
by_封爱 版主 2019-09-10
  • 打赏
  • 举报
回复
引用 10 楼 wanghui0380 的回复:
一点都不麻烦 https://www.cnblogs.com/jin-/p/9708360.html 这个是使用postsharp的
感谢大佬回复,,我刚看了下postsharp, 跟我的需求好像是一些区别.. 这个东西好像webapi里的filter 能捕获执行"方法"的参数. 但是针对我的需求 我有2点不同于这个东西, 第一.我针对是是"参数"而非方法.. 第二,我要去拦截参数并且重新赋值..

void md(int i)
{
 cw(i);
}
add(5);
这样输出的是5 我想实现的是

void md([特性]int i)
{
 cw(i);
}
当我加了特性之后.我拦截参数.

add(5);
输出50 也就是*10, 但是这个*10的操作是在哪呢? 就是在特性里拦截.

public class 特性:什么东西
{
    public overrid  什么方法(参数 [] )
    {
         if(typeof(参数)==int)
         {
                base.结果=参数*10;
         }
    }
}
类似这种东西吧.. 虽然我不知道能否实现,只是碰到这样一个需求而已.
wanghui0380 2019-09-10
  • 打赏
  • 举报
回复
实际上这些东西,在nuget上很常见,如果你现在下nuget上那些代码,在7成的源代码都能看到这样一个东西(话说你还号称自己不看源代码么,你不看源代码,自然就看不到,别人其实已经用了很多年了,在nuget上都是一个常态应用了) xxxx([notNull]xxxx) 这个东西就是 有关这类东西的搞法,用postsharp搞是这样的 http://badecho.com/2011/11/validating-method-parameters-with-postsharp/
正怒月神 2019-09-10
  • 打赏
  • 举报
回复
引用 10 楼 wanghui0380 的回复:
一点都不麻烦 https://www.cnblogs.com/jin-/p/9708360.html 这个是使用postsharp的,这是编译期静态IL织入型的,使用上是最简单的,基本没有编码期侵入代码。(当然这个如果你写的不好,异常了调试就麻烦,因为他的代码压根就不在你的源代码里面,这是编译时嵌入进去的) ps:我个人喜欢这个,因为他不侵入代码,你的代码逻辑简单,不用去折腾啥代理,emit,同时因为是IL直接织入,就相当原生IL,性能也ok。当然postsharp是个收费的东西 另外我个人建议,如果真想玩这个,你们还是好好看看"元数据编程","声明式编程"这类东西,不然整天被XX园牵着,连人家思维方式就搞不清就开始有模学样(东施效颦,邯郸学步------不是说人家潇洒,你那样也潇洒。)
这种类型的aop肯定能实现,其实只要使用mvc的filter就可以了。 但是楼主的想法是在参数前增加过滤器,类似FromBody。 我理解下来,可能多个参数还能使用不同的过滤器来走不同的验证。而不是我们说的常规的在方法头的aop
wanghui0380 2019-09-10
  • 打赏
  • 举报
回复
一点都不麻烦 https://www.cnblogs.com/jin-/p/9708360.html 这个是使用postsharp的,这是编译期静态IL织入型的,使用上是最简单的,基本没有编码期侵入代码。(当然这个如果你写的不好,异常了调试就麻烦,因为他的代码压根就不在你的源代码里面,这是编译时嵌入进去的) ps:我个人喜欢这个,因为他不侵入代码,你的代码逻辑简单,不用去折腾啥代理,emit,同时因为是IL直接织入,就相当原生IL,性能也ok。当然postsharp是个收费的东西 另外我个人建议,如果真想玩这个,你们还是好好看看"元数据编程","声明式编程"这类东西,不然整天被XX园牵着,连人家思维方式就搞不清就开始有模学样(东施效颦,邯郸学步------不是说人家潇洒,你那样也潇洒。)
正怒月神 2019-09-10
  • 打赏
  • 举报
回复
这个就比较麻烦了。在参数前设置特性过滤。 感觉有难度。
wanghui0380 2019-09-04
  • 打赏
  • 举报
回复
总结 1.第一种编代码很友好,调试不友好。编代码和平时一样,但编译“隐藏生成了你看不见的东西”,所以一旦你实现的不好,错都不知道哪里错的 2.第2种编代码相当的不友好,调试嘛相对比第一种强点(不过强的有限)----------哎,如果他真的没问题,你们也不至于天天一群在折腾他了,就是编写不友好,你们要问,到底怎么用。调试不友好,你们一错也得过来问
wanghui0380 2019-09-04
  • 打赏
  • 举报
回复
这是动态代理的例子 https://www.cnblogs.com/duanjt/p/9441587.html 这两个很容易区别 第一个是编译期就隐藏生成代码,所以你可以按平时一样写代码,不需要特别处理 第2个是运行期动态加的,所以你需要使用一个代理代码,代理访问。(你看第2种的风格,是不是跟你们天天折腾的注入是一个风格)
wanghui0380 2019-09-04
  • 打赏
  • 举报
回复
但凡注入的,都需要有个代理。(或者IL织入) 元数据编程,毕竟他只是元数据不参与运行,如果想让元数据程序参与运行,只有两条路 1.编译期生成一段“看不见”的代码,典型如aspect https://www.xin3721.com/ArticlecSharp/c13461.html 这个例子其实就是楼上那位的答案 2.运行期用一个动态代理或emit动态去扩展方法,像你们说的webapi,那是因为在httphandler管道中有个代理类去统一代理访问
XBodhi. 2019-09-04
  • 打赏
  • 举报
回复
你需要判断 是否有 你的 自己定义的 attr ,入过有你在你自己的过滤器直接操作就可以。 反射可以获取 GetCustomAttributes 方法。
stherix 2019-09-04
  • 打赏
  • 举报
回复
这个获取不了啊 因为Attribute就只是一个标记,供其他代码来读取使用的 本身就不具备有处理数据的功能 当然,你可以用其他代码(比如AOP)读取到实际的数据后,再来把这个数据当做参数,调用Attribute中的方法
cocoxox 2019-09-04
  • 打赏
  • 举报
回复
虽然看不懂 但是感觉很流弊
加载更多回复(1)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧