趁着武汉疫情,在家研究原来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. nginx实现缓存功能

    Nginx从0.7.48版本开始,支持了类似Squid的缓存功能.这个缓存是把URL及相关组合当作Key,用md5编码哈希后保存在硬盘上,所以它可以支持任意URL链接,同时也支持404/301/302 ...

  2. $Poj1723/AcWing123\ Soldiers$ 排序

    $Poj$ $AcWing$ $Description$ $Sol$ 分别处理$x$坐标和$y$坐标.$y$坐标显然很好处理,就是排个序然后取中位数就好了.$x$没有$y$那么直接叭.所以我首先写了个 ...

  3. 什么是Ceph存储?什么是分布式存储?简单明了带你学Ceph--<1>

    Ceph存储介绍 为什么要用Ceph Ceph是当前非常流行的开源分布式存储系统,具有高扩展性.高性能.高可靠性等优点,同时提供块存储服务(rbd).对象存储服务(rgw)以及文件系统存储服务(cep ...

  4. Spring MVC 请求处理过程

    1.  2. 3. 4. 5. 6.

  5. 1086 就不告诉你 (15分)C语言

    做作业的时候,邻座的小盆友问你:"五乘以七等于多少?"你应该不失礼貌地微笑着告诉他:"五十三."本题就要求你,对任何一对给定的正整数,倒着输出它们的乘积. 输入 ...

  6. 小小知识点(二十五)5G关键技术——Massive MIMO(大规模天线阵列)和beamforming(波束成形)

    转自http://www.elecfans.com/d/949864.html 多输入多输出技术(Multiple-Input Multiple-Output,MIMO)是指在发射端和接收端分别使用多 ...

  7. vue报错 [Intervention] Ignored attempt to cancel a touchmove event with cancelable

    在vue开发中使用vue-awesome-swiper制作轮播图,手动拖动时会报错,解决方案: 需要滑动的标签 { touch-action: none; } -------------------- ...

  8. echarts设置网格线颜色

    xAxis: { type: 'value', //设置网格线颜色 splitLine: { show: true, lineStyle:{ color: ['#315070'], width: 1, ...

  9. Bonny手机APP试用体验

    在上周四(即6月13日)下午,应王建民老师的邀请,我参观了学长学姐们的软件设计评比以及专业交流的活动,看到了形形色色学长学姐设计出的软件我觉得非常有趣,并对学长学姐们设计的软件的种类与功能感到由衷的钦 ...

  10. rest实践3

    1.从mongodb的数据实体Document中获取其中一个字段的值,即例如:doc.getString("pid"),直接显示value. 2.当从网络上的网址url的图片直接弄 ...