创建引用 ActionFilters、HTTPContext 、 HTTPException 等的 .Net 标准库

Pra*_*han 4 c# asp.net class-library asp.net-core

我在 .Netcore 上编写了一堆 API。我有一些想要在所有 API 中使用的操作属性。我计划创建一个带有操作过滤器的标准库项目,并在所有 API 项目中引用相同的内容。但是,我不确定是否可以添加对 sytem.web 的引用。我收到一堆有关缺少属性的错误,并且无法找到 HTTPConext 和 HTTPException 类型。为 Web API 创建可重用的 actionfilter 属性的正确方法是什么?

iti*_*omi 5

有两种方法

1)如果您的库仅使用网络应用程序,您可以通过 nuget 添加到库

用于过滤器的 Microsoft.AspNetCore.Mvc.Abstractions

HttpContext 的 Microsoft.AspNetCore.Http.Abstractions

并使用库中的 HttpContext 创建共享过滤器和其他操作

2)使用DI。创建一些接口并在库中使用它,并在项目中创建它的实现类。之后使用 DI 注入您的类,该接口将被调用。

  • 您可以在桌面\网络或任何应用程序中使用它+
  • 无需库 +
  • 你不依赖于任何版本的 API +
  • 对于过滤器来说它不起作用 -
  • 您需要在每个项目中实现您的界面 -

示例从 .Net 标准库中的服务中的 HttpContext 获取 cookie

public interface ICookieAccessor
{
     string GetCookieValueByName(string name);
}

public class SomeServiceThatUsesCookie()
{
     private readonly ICookieAccessor _cookieAccessor;

     public SomeServiceThatUsesCookie(ICookieAccessor cookieAccessor){
           _cookieAccessor = cookieAccessor;
     }

     public string IWonnaCookie(string name){
           return _cookieAccessor.GetCookieValueByName(name);
     }
}
Run Code Online (Sandbox Code Playgroud)

并在Web项目中实现接口(即实现应该在每个项目中)

public class CookieAccessor: ICookieAccessor
{
         private readonly IHttpContextAccessor _httpContext;

         public class CookieAccessor(IHttpContextAccessor httpContext){
                _httpContext = httpContext;
         }

         public string GetCookieValueByName(string name){
                if (_httpContext.HttpContext.Request.Cookies.TryGetValue(name, 
                                                              out var value))
                {
                       return value;
                 }
                 return null;
         }
}
Run Code Online (Sandbox Code Playgroud)

并将其注入到您的WebApps启动文件ConfigureServices方法中

services.AddTransient<ICookieAccessor, CookieAccessor>();
services.AddTransient<SomeServiceThatUsesCookie>();
Run Code Online (Sandbox Code Playgroud)

比在某些控制器中使用您的服务

public class SomeContoller: Controller
{
      private readonly SomeServiceThatUsesCookie _someService;

      public SomeContoller(SomeServiceThatUsesCookie someService){
             _someService = someService;
      }

      public string GetCookieValue(string name){
             return _someService.IWonnaCookie(name);
      }
}
Run Code Online (Sandbox Code Playgroud)