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

[https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio](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

3. 在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](https://github.com/aspnet/AspNetCore.Docs/issues/12564)

才发现其实在官方2.2升3.1的文章有介绍,只是一开始没看,原文这样介绍的:
#### Custom authorization handlers[](https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#custom-authorization-handlers)

If the app uses custom [authorization handlers](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-3.1#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](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.filters.authorizationfiltercontext) (the resource type [provided by MVC filters](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-3.1#accessing-mvc-request-context-in-handlers)) will need to be updated to handle resources of type [RouteEndpoint](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.routing.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://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](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/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/](https://damienbod.com/2018/04/15/supporting-both-local-and-windows-authentication-in-asp-net-core-mvc-using-identityserver4/)

asp.net core 2.2升到3.1遇到的问题小记的更多相关文章

  1. 将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1.3X

    在上一篇文章ASP.Net Core 运行错误 Http Error 502.5 解决办法的最后有提到说,最推荐的升级办法是从2.0升级到2.1X版本. 操作如下 项目的例子直接使用https://g ...

  2. ASP.NET Core 3.0 自动挡换手动挡:在 Middleware 中执行 Controller Action

    最近由于发现奇怪的 System.Data.SqlClient 性能问题(详见之前的博文),被迫提前了向 .NET Core 3.0 的升级工作(3.0 Preview 5 中问题已被修复).郁闷的是 ...

  3. ASP.NET Core on K8S深入学习(1)K8S基础知识与集群搭建

    在上一个小系列文章<ASP.NET Core on K8S学习初探>中,通过在Windows上通过Docker for Windows搭建了一个单节点的K8S环境,并初步尝试将ASP.NE ...

  4. 开发一个带UI的库(asp.net core 3.0)

    在GitHub上有个项目,本来是作为自己研究学习.net core的Demo,没想到很多同学在看,还给了很多星,所以觉得应该升成3.0,整理一下,写成博分享给学习.net core的同学们. 项目名称 ...

  5. asp.net core mvc中自定义ActionResult

    在GitHub上有个项目,本来是作为自己研究学习.net core的Demo,没想到很多同学在看,还给了很多星,所以觉得应该升成3.0,整理一下,写成博分享给学习.net core的同学们. 项目名称 ...

  6. gRPC asp.net core自定义策略认证

    在GitHub上有个项目,本来是作为自己研究学习.net core的Demo,没想到很多同学在看,还给了很多星,所以觉得应该升成3.0,整理一下,写成博分享给学习.net core的同学们. 项目名称 ...

  7. ASP.NET Core 之 Identity 入门(一)

    前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...

  8. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  9. ASP.NET Core应用的错误处理[3]:ExceptionHandlerMiddleware中间件如何呈现“定制化错误页面”

    DeveloperExceptionPageMiddleware中间件利用呈现出来的错误页面实现抛出异常和当前请求的详细信息以辅助开发人员更好地进行纠错诊断工作,而ExceptionHandlerMi ...

随机推荐

  1. 分布式事务框架-seata初识

    一.事务与分布式事务 事务,在数据库中指的是操作数据库的最小单位,往大了看,事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消. 那为什么会有分布式事务呢 ...

  2. 从零开始のcocos2dx生活(五)ActionEase

    文章目录 sineEaseIn sineEaseOut sineEaseInOut expoEaseIn expoEaseOut expoEaseInOut easeIn easeOut easeIn ...

  3. 洛谷$P2598\ [ZJOI2009]$狼和羊的故事 网络流

    正解:网络流 解题报告: 传送门! 昂显然考虑最小割鸭$QwQ$,就考虑说每个土地要么属于羊要么属于狼,然后如果一条边上是栅栏一定是相邻两边所属不同. 所以考虑给所有羊向$S$连$inf$,所有狼向$ ...

  4. Mybatis是如何实现SQL防注入的

    Mybatis这个框架在日常开发中用的很多,比如面试中经常有一个问题:$和#的区别,它们的区别是使用#可以防止SQL注入,今天就来看一下它是如何实现SQL注入的. 什么是SQL注入 在讨论怎么实现之前 ...

  5. Java网络编程——UDP聊天程序

    UDP简介 UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据报.在OSI模型中,UDP位于第四层--传输层,处于IP协议额上一层.UDP有不提供数据报分组.组装以及不能对数据报排序 ...

  6. .NET Core 3.1和WorkerServices构建Windows服务

    介绍 ASP.NET Core 3增加了一个非常有意思的功能Worker Service.他是一个ASP.NET Core模板,他允许我们创建托管长期的运行的后台服务,这些服务具体实现IHostedS ...

  7. Win10删除桌面上的回收站、计算机、网络等图标

    解决方案: 桌面上鼠标右键,选择个性化 个性化窗口左边侧栏选择主题 移动至最下方点击"桌面图标设置"即可看到系统中的五个桌面图标

  8. 6.7 Mapreduce作业流JobControl和Oozie

    1.1  Mapreduce作业流JobControl和Oozie 更复杂的任务,需要多个mapreduce作业,形成作业流,而不是增加map和reduce的复杂度.复杂问题,可以用高级语言pig.h ...

  9. .Net Core - AgileHttp

    2020年新年将至,先预祝.Net Core越来越好. 做了这么多年一线开发,经常跟Http打交道.比如调用三方的Webservice,比如集成微信支付的时候服务端发起Prepay支付.特别是现在分布 ...

  10. oop(面向对象语言的三大特征):封装,继承,多态; (抽象),函数绑定

    封装/隐藏 : 通过类的访问限定符实现的   private    public 继承的意义之一:代码的复用 类的继承是指在一个现有类的基础上去构建一个新的类,构造出来的新类被称为派生类(子类),现有 ...