netcore3.1知识小结

前言

本文是对最近使用netcore遇到的知识点小结,以备后用。

依赖注入DI

注意需要在startup.cs中引入Microsoft.Extensions.DependencyInjection

构造函数注入

构造函数注入是默认的注册方式,在core中相对比较简单,本文不做详细介绍

1.对于注入的对象需要有一个接口,首先需要在startup.cs中的ConfigureServices中中注册服务

注册服务有三种类型:
Transient(瞬时)每次访问都会生成一个新的对象,这个生命周期最适合轻量级,无状态的服务。
Scoped(作用域)在同作用域,服务每个请求只创建一次。
Singleton(单例)全局只创建一次,在第一次被请求时创建。

 			services.AddMemoryCache();
            services.AddTransient<ITokenTool,TokenToolImp>();//添加工具接口类
            services.Scoped<AuthorizeFilterAttribute>();//添加权限验证单例
            services.AddSingleton<ICache,MemoryCacheImp>();//添加缓存接口类

2.在构造器中注入

	private readonly ITokenTool _tokenTool;
    public WeatherForecastController(ITokenTool tool)
            {
                _tokenTool = tool;
            }

3.在Action中注入加上[FromServices]标记就可以了

 public ResponseModel<string> Login(string name,string pwd,[FromServices]ITokenTool tool,[FromServices]ICache cache)

拦截器中注入TypeFilter和ServiceFilter

对于在拦截器中注入,因为其需要无参构造启动,所以方式有点不一样,其他方式:TypeFilter和ServiceFilter

  1. ServiceFilter

如上,先实现拦截器后,在构造器中注入,然后在标记的时候我们需要改成下面的方式

 [ServiceFilter(typeof(MyFilter))]
 public IActionResult Index(){ return View();}
  1. TypeFilter

和上面的方式差不多,它和ServiceFilter的区别是它不从DI容器中创建实例,所以不需要在ConfigureServices中进行注册就能使用。
并且TypeFilter的生命周期是瞬时的我们无法控制,而ServiceFilter我们可以在注册时自己调整

 [TypeFilter(typeof(MyFilter))]
 public IActionResult Index(){ return View();}

3.全局的拦截器注入可以看下面

其他方式注入

不推荐,此处不讲,如有需要了解的朋友,可以查看下面这篇博客:
替换ioc容器,使用Autofac通过构造函数和属性注入两种方式讲解

全局拦截器

此次我使用了两种全局拦截器,actionFilter和中间件形式:

中间件全局异常拦截器

  1. 创建GlobalExceptionMiddleware类

     >此类必须有一个RequestDelegate字段,并且在构造中注入;
     >必须有一个invoke()方法
    
public class GlobalExceptionMiddleware
    {
        private readonly RequestDelegate next;
        public GlobalExceptionMiddleware(RequestDelegate next)
        {
            this.next = next;
        }
        public async Task Invoke(HttpContext context)
        {
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {
                await HandlerExceptionAsync(context, ex);
            }
        }

        private Task HandlerExceptionAsync(HttpContext context, Exception ex)
        {
            var code = HttpStatusCode.OK;
            var result = JsonConvert.SerializeObject(new ResponseModel{Message=ex.Message,Description=HttpStatusCode.Unauthorized.ToString()});
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)code;
            return context.Response.WriteAsync(result);
        }
    }
  1. 然后在Startup.cs中的configure方法中注册
    app.UseMiddleware(typeof(GlobalExceptionMiddleware));

action权限过滤全局拦截器

此方法相对简单,此处主要讲全局实现
3. 继承ActionFilterAttribute类
4. 在startup.cs中的ConfigureServices方法中注册filter,如下

这种方式有个问题,他在创建实例的时候会走默认的无参构造函数,如果我们有在拦截器中注入其他对象,则会报异常

services.AddControllers(option=>
{
      option.Filters.Add<AuthorizeFilterAttribute>();
  });
  1. 使用服务的方式注册拦截器,实现拦截器中注入

是不是很简单!!!

services.AddControllers(option=>
{
      option.Filters.AddService<AuthorizeFilterAttribute>();
  });

拦截器中获取属性

    var action=context.ActionDescriptor as ControllerActionDescriptor;
    var list=action.MethodInfo.GetCustomAttributesData().Where(t=>t.AttributeType==typeof(NoAuthorizeAttribute)).ToList()

自定义user类赋值给context.HttpContext.User

  1. **先实现UserPrincipal **
  public class TokenModel
    {
        public int UserId{set;get;}
        public int EntId{set;get;}
        public DateTime ExpirationTime{set;get;}
        public string Ip{set;get;}
    }
    public class UserPrincipal :ClaimsPrincipal 
    {
        public TokenModel User{set;get;}
        public UserPrincipal(TokenModel obj){
            User=obj;
        }
    }
  1. **在拦截器中赋值 **
 context.HttpContext.User=new UserPrincipal(user);
  1. **在action中使用 **
			var up=this.User as UserPrincipal;
            return up.User.EntId;

结合swagger

  1. 首先需要引入相关包:在终端控制台输入命令:
dotnet add YourProjectName.csproj package Swashbuckle.AspNetCore
  1. 在startup.cs ConfigureServices中添加如下服务:
  services.AddSwaggerGen(c=>
            {
                c.SwaggerDoc("v1",new OpenApiInfo{Title="MyApi",Version="v1"});
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
//这里是为webapi项目添加一个全局的token,方便测试
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "请放入token,已方便api测试.",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Scheme = "bearer",
                    Type = SecuritySchemeType.Http,
                    BearerFormat = "JWT"
                });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                    {
                        {
                            new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
                            },
                            new List<string>()
                        }
                    });
            });
  1. 在startup.cs Configure中添加如下:
 app.UseSwaggerUI(c=>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json","My API V1");
            });
  1. 启动项目,打开网址:https://localhost:5001/swagger
    在这里插入图片描述

使用缓存

在netcore中已经集成了缓存我们可以直接使用
在ConfigureServices中启用services.AddMemoryCache();然后就可以注入使用了。当然最好我们封装一个接口自己实现一下

 public interface ICache
    {
        bool SetCache<T>(string key,T value,DateTime? expireTime=null);
        bool RemoveCache(string key);
        T GetCache<T>(string key);
    } 
 public class MemoryCacheImp : ICache
    {
        private readonly IMemoryCache _cache;
        public MemoryCacheImp(IMemoryCache cache)
        {
            _cache=cache;
        }
       public T GetCache<T>(string key)
        {
            return _cache.Get<T>(key);
        }

        public bool RemoveCache(string key)
        {
            _cache.Remove(key);
            return true;
        }

        public bool SetCache<T>(string key, T value, DateTime? expireTime = null)
        {
            try
            {
                if(expireTime==null)
                {
                    return _cache.Set<T>(key,value)!=null;
                }else
                {
                    return _cache.Set<T>(key,value,expireTime.Value- DateTime.Now)!=null;
                }
            }catch
            {
                return false;
            }
            
        }
    }

获取配置文件

  1. 通过注入_configuration方式:
   public myclass(IConfiguration configuration)
           {
                _configuration = configuration;
           }
          public void fn()
          {
           var data=_configuration["test"];
             var data2=_configuration["Logging:LogLevel:Default"];
             }
  1. Json文件的弱类型方式读取:
private static void Main(string[] args)
{
    IConfiguration configuration = new ConfigurationBuilder()
        .SetBasePath(Environment.CurrentDirectory)
        .AddJsonFile("AppSettings.json",true,true)
        .AddInMemoryCollection()
        .Build();
    var str1 = configuration["DataBase:SqlServer:ConnectionString"];
    var str2 = configuration["endArray:0:endId"];
    Console.WriteLine($"{str1}+---{str2}");
}
  1. Json文件的强类型获取方式:
private static void Main(string[] args)
{
    IConfiguration configuration = new ConfigurationBuilder()
        .SetBasePath(Environment.CurrentDirectory)
        .AddJsonFile("AppSettings.json",true,true)
        .AddInMemoryCollection()
        .Build();

    //GetValue获取方式
    int val = configuration.GetValue<int>("endArray:0:endId");
    Console.WriteLine(val); 
}

启动端口配置

  1. Program中用userurls配置
public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseUrls("https://*:5001").UseStartup<Startup>();

                });
  1. Program中用UseConfiguration(config)配置.

此方式没做测试


        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                     var config = new ConfigurationBuilder()
					        .SetBasePath(Directory.GetCurrentDirectory())
					        .AddJsonFile("hosting.json", optional: true)
					        .Build();
        webBuilder.UseConfiguration(config);

                });
  1. 使用dotnet 命令启动时配置(推荐).
dotnet MyProject.dll --urls="https://localhost:7001;http://localhost:7000" --environment=Development

默认端口为5000(https为5001)

默认环境为Production
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值