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](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/)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM