从零开始搭建.NET Core 2.0 API(学习笔记一)

  从零开始搭建.NET Core 2.0 API(学习笔记一)

一、 VS 2017 新建一个项目 选择ASP.NET Core Web应用程序,再选择Web API,选择ASP.NET Core 2.0版本

二、 添加API帮助页面 API项目添加 NuGet NSwag.AspNetCore 引用, 然后在添加NSwag设置

运行项目 http://localhost:prot/swagger 即可打开帮助页。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{
  if (env.IsDevelopment())
  {
    app.UseDeveloperExceptionPage();
    app.UseBrowserLink();
  }
  else
  {
    app.UseExceptionHandler("/Home/Error");
  }

  app.UseStaticFiles();


app.UseSwaggerUi(typeof(Startup).GetTypeInfo().Assembly, settings =>
{
  settings.GeneratorSettings.DefaultPropertyNameHandling = PropertyNameHandling.CamelCase;
});

app.UseMvc(route =>
{
  route.MapRoute(name: "default", template: "{controller=Home}/{action=Get}/{id?}");
});

}

三、 Startup 类ConfigureServices方法中,添加配置中心初始化;配置中心统一管理配置,便于维护

public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            ConfigHelper.Init(Configuration["ConfigZookeeperAddress"], Configuration["ConfigNodePath"]);
            services.AddSingleton<ILogWrite, LogWrite>();

            services.AddMvc(options =>
            {
                options.Filters.Add<AuthorizationFilter>();
                options.Filters.Add<ExceptionFilter>();
                options.Filters.Add<PerformanceLogFilter>();
            });

            var builder = new ContainerBuilder();//实例化 AutoFac  容器            
            builder.Populate(services);

            // TODO: 这里添加其他需要注入类的注册

            ApplicationContainer = builder.Build();
            return new AutofacServiceProvider(ApplicationContainer);
        }

四、添加一个基础设置项目,添加一个日志接口 ILogWrite,一个记录日志实现类 LogWrite 在Startup 类ConfigureServices方法中添加日志 Ioc

因为日志拦截器和异常拦截器会用到日志记录需要注入 所以日志在AddMvc()前面添加,Autofac配置不能在 AddMvc前面,所以这里用.NET Core的Ioc容器,后面Autofac会接管容器。

services.AddSingleton<ILogWrite, LogWrite>();

五、filter 添加三个类分别是

  a AuthorizationFilter 权限过滤器

  b ExceptionFilter 异常过滤器

  c PerformanceLogFilter 性能日志过滤器

  ExceptionFilter 、PerformanceLogFilter 分别定义构造函数,注入日志依赖。

public ExceptionFilter(ILogWrite logWrite)
{
  _logWrite = logWrite;
}

public PerformanceLogFilter(ILogWrite logWrite)
{
  _logWrite = logWrite;
}

过滤器必须添加在 Startup类ConfigureServices的services.AddMvc()中

services.AddMvc(options =>
{
    options.Filters.Add<AuthorizationFilter>();
    options.Filters.Add<ExceptionFilter>();
    options.Filters.Add<PerformanceLogFilter>();
});

 

六、Action参数读取,为了在异常过滤器、性能日志过滤器中,读取参数需要在权限过滤器中添加下面两行代码

public class AuthorizationFilter : IAuthorizationFilter
{
  public void OnAuthorization(AuthorizationFilterContext context)
  {
    HttpRequest request = context.HttpContext.Request;
    request.EnableRewind();
    request.Body.Position = 0;
  }
}

七、性能日志过滤器 PerformanceLogFilter 继承 IActionFilter,实现两个接口

    OnActionExecuting 在调用操作方法之前发生
    OnActionExecuted 在调用操作方法之后发生
  a 在方法 OnActionExecuting中 实例化一个 Stopwatch 用于记录方法开支执行时间
    把Stopwatch 实力加入 HttpContext.Items 中,便于在 OnActionExecuted 获取。

  b 读取Action请求参数, 放入 HttpContext.Items 中, 不知道为什么OnActionExecuted 去不到参数

     /// <summary>
        /// 在调用操作方法之前发生。
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuting(ActionExecutingContext context)
        {
       //
if (SkipLogging(context)) return; var watch = new Stopwatch(); context.HttpContext.Items[ConfigHelper.HttpRequestStopWatcher] = watch; var paramenters = context.ActionArguments.Count==0?string.Empty:context.ActionArguments.Serialize(); context.HttpContext.Items[ConfigHelper.FilterActionArguments] = paramenters; watch.Start(); }

OnActionExecuting 中增加了性能日志开关,如果关闭直接返回,不创建Stopwatch,
在OnActionExecuted中回去到的Stopwatch是null 则直接返回(也可以用性能日志开关做判断),不处理后续。
如果Controll、Action添加了NoLog特性,则不记录性能日志

        private static bool SkipLogging(ActionExecutingContext actionContext)
        {
            if (!ConfigHelper.IsPerformanceLog) return true;
            return actionContext.ActionDescriptor.GetType().GetCustomAttributes(typeof(NoLogAttribute), false).Any() ||
                   actionContext.Controller.GetType().GetCustomAttributes(typeof(NoLogAttribute), false).Any();
        }
  
/// <summary>   /// 忽略性能日志记录特性   /// </summary>   [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]   public class NoLogAttribute : Attribute   {   }

八、异常过滤器

   /// <summary>
    /// 异常拦截器
    /// </summary>
    public class ExceptionFilter : IExceptionFilter
    {
        ILogWrite _logWrite;
        public ExceptionFilter(ILogWrite logWrite)
        {
            _logWrite = logWrite;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public void OnException(ExceptionContext context)
        {
            BizResult<bool> biz;

            var paramenters = context.HttpContext.Items[ConfigHelper.FilterActionArguments].ToString();
            try
            {
                biz = new BizResult<bool>(false, (int)B2CBizCode.Exception, context.Exception.Message);

                if (context.Exception.InnerException != null)
                    biz.SysMessage += ":" + context.Exception.InnerException.Message;

                if (ConfigHelper.IsPerformanceLog)
                {
                    var watch = context.HttpContext.Items[ConfigHelper.HttpRequestStopWatcher] as Stopwatch;
                    watch?.Stop();

                    var name = context.ActionDescriptor.GetType().GetProperty("ActionName").GetValue(context.ActionDescriptor).ToString();

                    _logWrite.InfoAsync(new 
                    {
                        CreateTime = DateTime.Now,
                        Method = name,
                        TimeSpan = watch.Elapsed,
                        IsSuccess = false,
                        Content = paramenters,
                        Code = ((B2CBizCode)biz.BusinessCode).ToString(),
                        Message = biz.BusinessMessage
                    }.Serialize());
                }
            }
            catch (Exception ex)
            {
                biz = new BizResult<bool>(false, (int)B2CBizCode.Exception, ex.Message);
            }
            context.Result = new ApplicationErrorResult(biz);

            _logWrite?.ErrorAsync($"链接访问出错:{context.HttpContext.Request.Path}", context.HttpContext.Request.Method, this.GetType().Name, context.Exception, paramenters);
            return;
        }
    }

    public class ApplicationErrorResult : ObjectResult
    {
        public ApplicationErrorResult(object value) : base(value)
        {
            StatusCode = (int)HttpStatusCode.InternalServerError;
        }
    }

 

 九 、添加Autofac,Autofac比.NET Core自带的 Ioc更好用。 NuGetAPI 项目中添加Autofac.Configuration、Autofac.Extensions.DependencyInjection 两个引用 然后 ConfigureServices方法中添加Ioc容器

     public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            ConfigHelper.Init(Configuration["ConfigZookeeperAddress"], Configuration["ConfigNodePath"]);
            services.AddSingleton<ILogWrite, LogWrite>();

            services.AddMvc(options =>
            {
                options.Filters.Add<AuthorizationFilter>();
                options.Filters.Add<ExceptionFilter>();
                options.Filters.Add<PerformanceLogFilter>();
            });

            var builder = new ContainerBuilder();//实例化 AutoFac  容器            
            builder.Populate(services);

            // TODO: 这里添加其他需要注入类的注册

            ApplicationContainer = builder.Build();
            return new AutofacServiceProvider(ApplicationContainer);
        }

 

至此.NET Core API的 拦截器、配置管理、日志、Ioc 设置已完成。

 

 

 public IServiceProvider ConfigureServices(IServiceCollection services)        {            ConfigHelper.Init(Configuration["ConfigZookeeperAddress"], Configuration["ConfigNodePath"]);            services.AddSingleton<ILogWrite, LogWrite>();
            services.AddMvc(options =>            {                options.Filters.Add<AuthorizationFilter>();                options.Filters.Add<ExceptionFilter>();                options.Filters.Add<PerformanceLogFilter>();            });
            var builder = new ContainerBuilder();//实例化 AutoFac  容器                        builder.Populate(services);
            // TODO: 这里添加其他需要注入类的注册
            ApplicationContainer = builder.Build();            return new AutofacServiceProvider(ApplicationContainer);        }

转载于:https://www.cnblogs.com/Dpgg/p/9595221.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值