asp.net core 2.2升到3.1遇到的问题小记

趁着武汉疫情,在家研究原来2.2的框架升级到3.1的问题,在过程中遇到不少坑,好在放假有的是时间,一个一个解决,现做个简要记录,供大家参考。
推荐认真看这篇文章

https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio

其中,主要问题都是原来的包的版本依赖问题!花了很多时间去解决各个引用的包依赖的问题

1.常见的其他网站都有提,比如:
移除包Microsoft.AspNetCore.App,已经不需要了

2.IHostingEnvironment变成了IWebHostEnvironment

  1. 在Microsoft.AspNetCore.Http.HttpRequest.EnableRewind()这个方法,升级为Request.EnableBuffering ()

4.如果出现:
System.TypeLoadException:“Could not load type 'Microsoft.AspNetCore.Mvc.MvcJsonOptions' from assembly 'Microsoft.AspNetCore.Mvc.Formatters.Json, Version=3.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.”
最后升级swagger版本g到最新的5.0得到解决,但是升级swagger,又发现:
IDocumentFilter 更改了接口,
命名空间也修改了:升级为using Microsoft.OpenApi.Models;
将tag=>OpenApiTag
原来的接口方法修改为:
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)

swagger示例:

 services.AddSwaggerGen(options =>
                                   {
                                       options.SwaggerDoc("v1", new OpenApiInfo
                                       {
                                           Title = "API接口文档",
                                           Version = "v1",
                                           Description = "API v1",
                                           Contact = new OpenApiContact { Name = "wadereye", Email = "wader129-qq.com" }
                                       });
                                       options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                                       {
                                           Description = "......",
                                           Name = "Authorization",
//这两个参数均有修改
                                           In = ParameterLocation.Header,
                                           Type = SecuritySchemeType.ApiKey
                                       });

                                       options.AddSecurityRequirement(new                               OpenApiSecurityRequirement {
                                               {
                                                 new OpenApiSecurityScheme
                                                 {
                                                   Reference = new OpenApiReference
                                                   {
                                                     Type = ReferenceType.SecurityScheme,
                                                     Id = "Bearer"
                                                   }
                                                  },
                                                  new string[] { }
                                                }
                                              });

...             
                                   });

5.如果出现:

System.MissingMethodException:“Method not found: 'Autofac.Builder.DeferredCallback Autofac.ContainerBuilder.RegisterCallback(System.Action`1<Autofac.Core.IComponentRegistry>)'.”

是autofac的版本问题,autofac我一开始更新到5.0,到处报错,后来查看5.0的文档,发现更新较多,于是又将相关的autofac 5.0包降到最新的4.9.4,很多问题得以解决。

6.如果你以前用过context.Resource as AuthorizationFilterContext这样的,在asp.net core 3.0已经不支持了。这个坑了我半天才找到解决方案。
在issue里找到这篇文章:
https://github.com/aspnet/AspNetCore.Docs/issues/12564

才发现其实在官方2.2升3.1的文章有介绍,只是一开始没看,原文这样介绍的:

Custom authorization handlers

If the app uses custom authorization handlers, endpoint routing passes a different resource type to handlers than MVC. Handlers that expect the authorization handler context resource to be of type AuthorizationFilterContext (the resource type provided by MVC filters) will need to be updated to handle resources of type RouteEndpoint (the resource type given to authorization handlers by endpoint routing).

MVC still uses AuthorizationFilterContext resources, so if the app uses MVC authorization filters along with endpoint routing authorization, it may be necessary to handle both types of resources.

google翻译如下:
自定义授权处理程序 如果应用使用自定义授权处理程序,则端点路由会将与MVC不同的资源类型传递给处理程序。期望授权处理程序上下文资源的类型为AuthorizationFilterContext(由MVC过滤器提供的资源类型)的处理程序将需要更新,以处理RouteEndpoint类型的资源(端点路由提供给授权处理程序的资源类型)。
MVC仍使用AuthorizationFilterContext资源,因此,如果应用程序使用MVC授权过滤器以及端点路由授权,则可能有必要处理两种类型的资源。

所以获取的方式变了,很多需要通过endpoint的方式去获取。

具体的可以通过这篇文章来了解详细:

https://damienbod.com/2019/12/02/using-http-request-routes-request-body-and-query-string-parameters-for-authorization-in-asp-net-core/

示例代码 可以看:
https://github.com/damienbod/AspNetCoreWindowsAuth

简要点说:作者建议这样玩:
(1)在ASP.NET核心中使用HTTP请求路由,请求主体和查询字符串参数进行授权

使用ASP.NET Core Route参数进行授权
An AuthorizationHandler can be used to implement authorization logic in ASP.NET Core. The handler can authorize HTTP requests using a route parameter from where the policy for the requirement used in the handler is defined. The IHttpContextAccessor is used to access the route parameters. The RouteValues property in the request of the HttpContext contains these values. If you know the name of the route value, the value can be retrieved using this key. In this demo, a static text is used to validate the route parameter value. In a real world AuthorizationHandler, the value would be validated against a claim from the token, or queried from a database, or an authorization service. To validate this correctly, something must be used which cannot be manipulated. If using a claim from the access token, then the access token must be validated fully and correctly. The AuthorizationHandler implements the ValuesRouteRequirement which is used in the policy definition.

可以使用AuthorizationHandler在ASP.NET Core中实现授权逻辑。处理程序可以使用route参数授权HTTP请求,从中定义处理程序中使用的需求策略。 IHttpContextAccessor用于访问路由参数。 HttpContext请求中的RouteValues属性包含这些值。如果知道路由值的名称,则可以使用此键检索该值。在此演示中,使用静态文本来验证路由参数值。在现实世界中的AuthorizationHandler中,将根据令牌中的声明对值进行验证,或者根据数据库或授权服务对其进行查询。为了正确验证这一点,必须使用一些无法操纵的东西。如果使用访问令牌中的声明,则必须完全正确地验证访问令牌。 AuthorizationHandler实现在策略定义中使用的ValuesRouteRequirement。

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
 
namespace AppAuthorizationService
{
    public class ValuesCheckRouteParameterHandler : AuthorizationHandler<ValuesRouteRequirement>
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
 
        public ValuesCheckRouteParameterHandler(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
 
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ValuesRouteRequirement requirement)
        {
            var routeValues = _httpContextAccessor.HttpContext.Request.RouteValues;
 
            object user;
            routeValues.TryGetValue("user", out user);
            if ( user.ToString() == "phil")
            {
                context.Succeed(requirement);
            }
 
            return Task.CompletedTask;
        }
    }
}

In the Startup class using the ConfigureServices method, the IAuthorizationHandler services are registered and also the IHttpContextAccessor using the AddHttpContextAccessor method. The policies are defined for the authorization requirements. The demo is an API project example, which uses swagger so the AddControllers extension method is used, with AddNewtonsoftJson.

在使用ConfigureServices方法的Startup类中,将注册IAuthorizationHandler服务,并使用AddHttpContextAccessor方法来注册IHttpContextAccessor。为授权要求定义了策略。该演示是一个API项目示例,该示例使用了大张旗鼓,因此将AddControllers扩展方法与AddNewtonsoftJson一起使用。

public void ConfigureServices(IServiceCollection services)
{
    // ...
 
    services.AddHttpContextAccessor();
 
    services.AddSingleton<IAuthorizationHandler, ValuesCheckQueryParameterHandler>();
    services.AddSingleton<IAuthorizationHandler, ValuesCheckRequestBodyHandler>();
    services.AddSingleton<IAuthorizationHandler, ValuesCheckRouteParameterHandler>();
 
    services.AddAuthorization(options =>
    {
        options.AddPolicy("protectedScope", policy =>
        {
            policy.RequireClaim("scope", "native_api");
        });
        options.AddPolicy("ValuesRoutePolicy", valuesRoutePolicy =>
        {
            valuesRoutePolicy.Requirements.Add(new ValuesRouteRequirement());
        });
        options.AddPolicy("ValuesQueryPolicy", valuesQueryPolicy =>
        {
            valuesQueryPolicy.Requirements.Add(new ValuesCheckQueryParamRequirement());
        });
        options.AddPolicy("ValuesRequestBodyCheckPolicy", valuesRequestBodyCheckPolicy =>
        {
            valuesRequestBodyCheckPolicy.Requirements.Add(new ValuesRequestBodyRequirement());
        });
    });
 
 
    services.AddControllers()
        .AddNewtonsoftJson();
}

The policy is then used in the controller in the authorize attribute. In this demo, if the user has the value ‘phil’, the data will be returned, otherwise a 403 is returned, or 401 if no bearer access token is sent in the header of the HTTP request.

然后在控制器的authorize属性中使用该策略。在此演示中,如果用户的值为“ phil”,则将返回数据,否则返回403,或者如果在HTTP请求的标头中未发送任何承载访问令牌,则返回401。

[Authorize("ValuesRoutePolicy")]
[ProducesResponseType(StatusCodes.Status200OK)]
[HttpGet]
[Route("{user}", Name = nameof(GetWithRouteParam))]
public IActionResult GetWithRouteParam([FromRoute]string user)
{
    return Ok($"get this data [{user}] using the route");
}

A HttpClient implementation can then make a HTTP request with the route set and the access token added to the headers.

然后,HttpClient实现可以发出带有路由集并将访问令牌添加到标头的HTTP请求

'''
private static async Task CallApiwithRouteValue(string currentAccessToken, string user)
{
_apiClient.SetBearerToken(currentAccessToken);
var response = await _apiClient.GetAsync($"/api/values/{user}");

if (response.IsSuccessStatusCode)
{
    var result = await response.Content.ReadAsStringAsync();
    Console.WriteLine($"\n{result}");
}
else
{
    Console.WriteLine($"Error: {response.ReasonPhrase}");
}

}
'''

后面还有更详细的基于querystring的方法,我就不写了,看一下就明白 了。
另外推荐这几篇文章也看下:

https://damienbod.com/2018/04/19/asp-net-core-authorization-for-windows-local-accounts/

https://damienbod.com/2018/04/15/supporting-both-local-and-windows-authentication-in-asp-net-core-mvc-using-identityserver4/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容