如何在调用方法时启动的方法上添加属性?

时间:2017-10-20 17:57:17

标签: c# attributes .net-core asp.net-core-2.0

我有一个非常标准的.net核心2 WebApi项目。我想在一个方法上添加一个属性,该方法将在调用操作时启动。

在下面的伪代码中,每当有人发帖到foo操作时,我都想记录POST的正文。为此,我添加了[LogBody]属性。但我不知道如何真正启动属性中的方法。

class SomeController: Controller {
    [HttpPost]
    [LogBody]
    public void foo([FromBody] SomeObj obj) {
        return View(obj);
    }
}

class LogBodyAttribute: Attribute {
    void LogIt() {
        string methodName = getMethodName();
        string body = new StreamReader(Request.Body, Encoding.UTF8).ReadToEnd();

        SaveData(methodName, body);
    }
}

P.S。我知道我可以用PostSharp做到这一点,但我宁愿不这样做。

2 个答案:

答案 0 :(得分:2)

属性提供包含在已编译代码中的静态元数据。可以在运行时查询此信息并用于执行逻辑;但是,属性本身不能触发动作。

给定一个对象,你可以得到这样的属性:

Type type = controller.GetType();
var myAttribute = type
    .GetMethod(methodName)
    .GetCustomAttributes(true)
    .OfType<MyAttribute>()
    .FirstOrDefault();

GetCustomAttributes的布尔参数表示是否必须返回继承的属性。

也许您正在寻找的是Aspect-oriented programming AOP。这允许您在后编译过程中将代码注入方法和属性。属性可用于包含或排除方法。 C#有不同的AOP产品。

另一种方法是使用Decorator pattern。装饰器是一个包装类,提供与包装类相同的API,并允许向包装的方法和属性添加行为。与inversion of control(IoC)容器或Factory method pattern一起使用时,可以自动注入行为。

答案 1 :(得分:2)

可以做到,但这并不容易 - 你的问题的直接答案涉及反射和代码注入的东西。这是一个可以帮助您做您想做的SO问题:C# Attribute to trigger an event on invoking a method