C#特性(Attribute)讲解

1.特性的介绍与使用

特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。

特性的使用方法很简单,只需要写在方法,类,枚举,字段等程序体的上面用[]括起来即可,如下。

    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestController:ControllerBase
    {
        [HttpGet]
        [Obsolete]
        public void Test()
        {
            Console.WriteLine("这是一个过时的方法");
        }
    }

一般都支持多个特性。

2. .Net自带的三种预定义特性

AttributeUsage
AttributeUsage仅对继承自Attribute的派生类有效,目的是控制当前类的使用范围。比如下面这段代码,我定义了一个TestUser的自定义特性,在AttributeUsage参数里传入了AttributeTargets.Method这个参数,指定当前特性仅对方法有效。

 [AttributeUsage(AttributeTargets.Method)]
    class TestUserAttribute : Attribute
    {
       public static void Test()
       {
       }
    }

那我当我在使用这个特性的时候。就只能定义在方法的上面。

    [TestUser]
    static void Main(string[] args)
    {
        Test();
        Console.WriteLine("Hello, World!");
    }

如果放到其他的结构上面,则会报错。
在这里插入图片描述
如果需要指定对多种程序体有效的话,这里写多个目标,中间用 | 隔开,或者指定AttributeTargets.All,表示对所有程序体有效。

//仅对方法和类有效
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,AllowMultiple =true)]
class TestUserAttribute : Attribute
  {
     public static void Test()
     {
     }
  }
//对所有结构有效
[AttributeUsage(AttributeTargets.All,AllowMultiple =true)]
class TestUserAttribute : Attribute
  {
     public static void Test()
     {
     }
  }

AttributeTargets是一个枚举,包括以下内容。
在这里插入图片描述

Obsolete
该特性可以用来声明程序体是过时的,被弃用的。

  [Obsolete("该方法已过时,请使用TestNew",true)]
  static void Test()
    {
        Console.WriteLine("这是一个被过时的方法");
    }
    static void TestNew()
    {
        Console.WriteLine("这是一个最新的方法");
    }

Obsolete有三个重载。
ObsoleteAttribute() 表示该程序体是被弃用的。
ObsoleteAttribute(string? message) 可以输入提示内容,在鼠标移动到程序体名称上时显示。
ObsoleteAttribute(string? message, bool error) bool参数用来表示该方法是否弃用,若为true,则该程序体不能被使用。默认为false

Conditional
Conditional位于System.Diagnostics命名空间下
这个特定通过条件判断决定是否运行下面对应的程序体。比如下面这样,我传了一个字符串Debug,但是并没有定义这个字符串,那么这个方法就不会执行。
在这里插入图片描述
如果在最上面定义了Debug,则这个方法就会执行。
在这里插入图片描述

3.常用的特性

在命名空间 Microsoft.AspNetCore.Mvc下,有很多定义好的特性,接下来我会挑部分常用的特性做简单介绍。.NET Core 3.1版本。
RouteAttribute
作用域:Class ,Method
说明:使用给定的路由模板创建一个新的。
ApiControllerAttribute
作用域:Assembly,Class
说明:指示使用类型和所有派生类型提供 HTTP API 响应。
HttpGetAttribute
作用域:All
说明:标识支持 HTTP GET 方法的操作。
HttpPostAttribute
作用域:All
说明:标识支持 HTTP POST 方法的操作。
HttpPutAttribute
作用域:All
说明:标识支持 HTTP PUT 方法的操作。
HttpDeleteAttribute
作用域:All
说明:标识支持 HTTP DELETE 方法的操作。
FromBodyAttribute
作用域:Property,Parameter
说明:指定应使用请求正文绑定参数或属性。
FromFormAttribute
作用域:Property,Parameter
说明:指定应在请求正文中使用表单数据绑定参数或属性。
FromHeaderAttribute
作用域:Property,Parameter
说明:指定应使用请求标头绑定参数或属性。
FromQueryAttribute
作用域:Property,Parameter
说明:指定应使用请求查询字符串来绑定参数或属性。
FromRouteAttribute
作用域:Property,Parameter
说明:指定应使用当前请求中的路由数据来绑定参数或属性。
FromServicesAttribute
作用域:Parameter
说明:指定应该使用请求服务绑定操作参数。
ActionContextAttribute
作用域:Property
说明:指定在创建控制器时应使用当前设置控制器属性 ActionContext 。 该属性必须具有公共集方法。
ActionNameAttribute
作用域:Method
说明:指定操作的名称。
AreaAttribute
作用域:Class ,Method
说明:指定包含控制器或操作的区域。
ControllerAttribute
作用域:Class
说明:指示将此特性应用于的类型和任何派生类型被默认控制器发现机制视为控制器,除非 NonControllerAttribute 应用于层次结构中的任何类型。
ControllerContextAttribute
作用域:Property
说明:指定在创建控制器时应使用当前设置控制器属性 ControllerContext 。 该属性必须具有公共集方法。
FormatFilterAttribute
作用域:Class,Method
说明:一个筛选器,它将使用路由数据或查询字符串中的格式值对从操作返回的 ObjectResult 设置内容类型。

4.自定义特性

我们还是用.NET 的web项目做示范,写一个用特性来捕获异常的方法。首先定义一个特性类。继承自AttributeIExceptionFilter
CatchExceptionAttribute.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Nlog_demo
{
    public class CatchExceptionAttribute : Attribute, IExceptionFilter
    {
        public CatchExceptionAttribute()  
        {
        }
        /// <summary>
        /// 发生异常进入
        /// </summary>
        /// <param name="context"></param>
        public async void OnException(ExceptionContext context)
        {
             ContentResult result = new ContentResult
            {
                StatusCode = 500,
                ContentType = "text/json;charset=utf-8;"
            };
            result.Content = "啊哦,出现异常了。";
            context.Result = result;
            context.ExceptionHandled = true;
        }
    }
}

接着在statup中注册一下。

builder.Services.AddScoped<CatchExceptionAttribute>();

然后在方法中就可以使用了,在方法上面加上特性名就可以了。下面的代码string转int肯定会报错的。

 [CatchException]
 public IActionResult Index()
  {
      var a = "hello world";
      var b = Convert.ToInt32(a);
      return View();
  }

运行效果如下。
在这里插入图片描述

项目报错,同时控制台也打印了一个输出。如果不想页面出现这样的提示的话,可以把
OnException方法修改如下。

  public async void OnException(ExceptionContext context)
  {
        ContentResult result = new ContentResult
        {
            StatusCode = 500,
            ContentType = "text/json;charset=utf-8;"
        };
        result.Content = "啊哦,出现异常了。";
        context.Result = result;
        context.ExceptionHandled = true;
    }

再次运行看看效果。
在这里插入图片描述

这次页面提示就是处理后的效果了。

Study hard and make progress every day.

  • 8
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李公子lm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值