www.九色_最新国产在线_国产精品资源_欧美a在线_www.黄.com_久久久久国产精品一区二区

歡迎來到財(cái)都網(wǎng)
主頁>炒股問答>Netcore【】

Netcore【】

財(cái)都網(wǎng)2023-01-10 19:41:21財(cái)都小生

正文

關(guān)鍵要點(diǎn)dotnet cli 使得基于. Net 項(xiàng)目的自動(dòng)化和腳本編寫變得非常簡單,尤其是與十多年前的. Net 技術(shù)相比。dotnet cli 可擴(kuò)展性模型創(chuàng)造了條件,使得通過 Nuget 將外部.NET 編寫的命令行程序集成到你的自動(dòng)化構(gòu)建中成為可能。dotnet cli 允許在你的構(gòu)建腳本中針對解決方案進(jìn)行測試。dotnet cli 的測試輸出有助于更好地使用持續(xù)集成 (CI)。使用 Docker 之類的容器技術(shù)比使用 dotnet cli 要容易得多。

隨著.NET Core 2.0 的發(fā)布,微軟擁有了通用、模塊化、跨平臺和開源平臺的下一個(gè)主要版本,該版本最初于 2016 年發(fā)布。.NET Core 已經(jīng)創(chuàng)建了許多 API,這些 API 在.NET 框架的當(dāng)前版本中是可用的。它最初是為了下一代 ASP.NET 解決方案創(chuàng)建的,但現(xiàn)在是許多其他場景的驅(qū)動(dòng)和基礎(chǔ),包括物聯(lián)網(wǎng)、云和下一代移動(dòng)解決方案。在關(guān)于.NET Core 的第二個(gè)系列的文章中,我們將進(jìn)一步探討.NET Core 的優(yōu)點(diǎn),以及它如何不僅有益于傳統(tǒng)的.NET 開發(fā)人員,也有益于所有需要為市場提供強(qiáng)健的、高效的和經(jīng)濟(jì)的解決方案的技術(shù)人員。

最近總有人問我,和那些要么遲疑,要么不能退出舊版本、全功能的.NET 的人相比,選擇.NET Core 的優(yōu)勢是什么?我在回答中會提到.NET Core 有更好的性能、改進(jìn)的 csproj 文件格式、改進(jìn)的 ASP 可測試性,并且它是跨平臺的。

作為幾個(gè) OSS 工具 (Marten、StructureMap,以及在這個(gè)項(xiàng)目中作為例子被引用的Alba) 的作者,對我個(gè)人而言最大的優(yōu)勢可能是dotnet cli的出現(xiàn)。我個(gè)人認(rèn)為,結(jié)合新的.NET SDK csproj文件格式一起使用時(shí),dotnet cli 工具使我可以更容易創(chuàng)建項(xiàng)目和維護(hù)構(gòu)建腳本。我可以更容易在構(gòu)建腳本中運(yùn)行測試,更容易使用和分發(fā) Nuget 包,cli 可擴(kuò)展性機(jī)制非常適合將通過 Nuget 包分發(fā)的自定義可執(zhí)行文件合并到自動(dòng)構(gòu)建中。

若要開始使用 dotnet cli,首先要在開發(fā)機(jī)器上安裝.NET SDK。安裝完成后,給你一些有用的提示:將“dotnet”工具全局安裝到你的 PATH 中,這樣在任何地方都可以通過命令行提示符使用它。dotnet cli 采用 Linux 風(fēng)格的命令語法,用“–word [value]”這種普通寫法表示選擇的參數(shù),或者直接用縮寫形式“-w [value]”。如果您習(xí)慣 Git 或 Node.js 命令行工具,就不會對 dotnet cli 感到陌生。“dotnet --help”將列出已安裝的命令和一些基本語法用法。“dotnet --info”將告訴你使用的是哪個(gè)版本的 dotnet cli。在持續(xù)集成構(gòu)建中調(diào)用此命令可能是一個(gè)好主意,以便在本地工作并在構(gòu)建服務(wù)器失敗時(shí)排除故障,反之亦然。盡管我在本文中討論的是.NET Core,但是請注意,你可以在完整.NET 框架的以前版本中使用新的 SDK 項(xiàng)目格式和 dotnet cli。

命令行中的 Hello World

為了簡單了解一下 dotnet cli 的一些亮點(diǎn),讓我們假設(shè)想構(gòu)建一個(gè)簡單的“Hello World”ASP.NET Core 應(yīng)用程序。不過,為了好玩,我們來添加一些新花樣:

1. 我們的 web 服務(wù)將在一個(gè)單獨(dú)的項(xiàng)目中進(jìn)行自動(dòng)化測試。

2. 我們將通過 Docker 容器部署我們的服務(wù),因?yàn)檫@是很酷的做法 (它展示了更多的 dotnet cli)。

3. 當(dāng)然,我們將盡可能多地使用 dotnet cli。

如果您想看到這段代碼的最終結(jié)果,請查看this GitHub repository。

首先,讓我們從一個(gè)名為“DotNetCliArticle”的空目錄開始,并打開您最喜歡的命令行工具到該目錄。我們將從使用“dotnet new”命令來生成解決方案文件和新項(xiàng)目開始。.NET SDK 附帶了幾個(gè)用于創(chuàng)建常見項(xiàng)目類型或文件的通用模板,以及其他可作為外接程序使用的模板 (稍后部分將對此進(jìn)行詳細(xì)介紹)。要查看在你的機(jī)器上可用的模板,可以使用以下命令 dotnet new -help,它應(yīng)該會給出如下輸出:Netcore【】(圖1)

你可能會留意到有一個(gè) sln 模板,它針對的是空解決方案文件。我們將使用該模板,鍵入 dotnet new sln 命令,該命令將生成以下輸出:

復(fù)制代碼

The template "Solution File" was created successfully.

默認(rèn)情況下,此命令將以包含的目錄命名解決方案文件。因?yàn)槲覍⒏夸浢麨闉椤癉otNetCliArticle”,所以生成的解決方案文件是“DotNetCliArticle.sln”。

接下來,讓我們用以下命令添加“Hello,World”的實(shí)際項(xiàng)目:

復(fù)制代碼

dotnet new webapi --output HeyWorld

上面的命令意思是將“webapi”模板用到通過“output”參數(shù)選擇的“HeyWorld”中。這個(gè)模板將生成一個(gè)精簡的 MVC Core 項(xiàng)目結(jié)構(gòu),適合于無頭 API。同樣,默認(rèn)的做法是根據(jù)所在的目錄命名項(xiàng)目文件,因此我們在目錄下得到一個(gè)名為“HeyWorld.csproj”的文件,以及所有基本文件,組成一個(gè)最小的 ASP.NET MVC Core API 項(xiàng)目。該模板還設(shè)置了所有必要的 Nuget 對 ASP.NET Core 的引用,我們在新項(xiàng)目啟動(dòng)時(shí)會用到它們。

由于我剛好在一個(gè)小型 Git 存儲庫中構(gòu)建了它,在使用 Git add 添加了任何新文件之后,我使用 Git status 查看新創(chuàng)建的文件:

復(fù)制代碼

new file: HeyWorld/Controllers/ValuesController.cs new file: HeyWorld/HeyWorld.csproj new file: HeyWorld/Program.cs new file: HeyWorld/Startup.cs new file: HeyWorld/appsettings.Development.json new file: HeyWorld/appsettings.json

現(xiàn)在,要將新項(xiàng)目添加到我們的空解決方案文件中,您可以像這樣使用“dotnet sln”命令:

復(fù)制代碼

dotnet sln DotNetCliArticle.sln add HeyWorld/HeyWorld.csproj

現(xiàn)在我們有了一個(gè)新的 ASP.NET Core API 服務(wù)作為外殼,無需打開 Visual Studio.NET(或者是 JetBrains Rider)。為了更進(jìn)一步,在編寫任何實(shí)際代碼之前啟動(dòng)我們的測試項(xiàng)目,我發(fā)出以下命令:

復(fù)制代碼

dotnet new xunit --output HeyWorld.Testsdotnet sln DotNetCliArticle.sln add HeyWorld.Tests/HeyWorld.Tests.csproj

上面的命令使用 xUnit.NET 創(chuàng)建一個(gè)新項(xiàng)目,并將該新項(xiàng)目添加到我們的解決方案文件中。測試工程需要對“HeyWorld”的工程引用,幸運(yùn)的是,我們可以使用很棒的“dotnet add”工具添加工程引用,如下所示:

復(fù)制代碼

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj reference HeyWorld/HeyWorld.csproj

在打開解決方案之前,我知道還有一些 Nuget 參考資料,我想在測試項(xiàng)目中使用它們。我選擇的斷言工具是Shoully,因此我將通過對命令行發(fā)出另一個(gè)調(diào)用來添加對最新版本的 shoully 的引用:

復(fù)制代碼

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj package Shouldly

命令行的輸出如下:

復(fù)制代碼

info : Adding PackageReference for package 'Shouldly' into project 'HeyWorld.Tests/HeyWorld.Tests.csproj'.log : Restoring packages for /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/HeyWorld.Tests.csproj...info : GET https://api.nuget.org/v3-flatcontainer/shouldly/index.jsoninfo : OK https://api.nuget.org/v3-flatcontainer/shouldly/index.json 109msinfo : Package 'Shouldly' is compatible with all the specified frameworks in project 'HeyWorld.Tests/HeyWorld.Tests.csproj'.info : PackageReference for package 'Shouldly' version '3.0.0' added to file '/Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/HeyWorld.Tests.csproj'.

接下來,我想向名為 Alba 的測試項(xiàng)目添加至少一個(gè) Nuget 引用。我將使用AspNetCore2來編寫針對新的 web 應(yīng)用程序的 HTTP 契約測試:

復(fù)制代碼

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj package Alba.AspNetCore2

現(xiàn)在,在使用代碼之前先檢查一下,我將在命令行發(fā)出以下命令構(gòu)建解決方案中的所有項(xiàng)目,確保它們都可以正常編譯:

復(fù)制代碼

dotnet build DotNetCliArticle.sln

由于 Alba.AspNetCore2 和 ASP.NET Core Nuget 在 HeyWorld 項(xiàng)目中的引用之間的菱形依賴版本的沖突,所以沒有編譯。不過不用擔(dān)心,因?yàn)檫@個(gè)問題很容易解決,只需修復(fù) Microsoft.AspNetCore 的版本依賴關(guān)系即可。測試項(xiàng)目中的所有 Nuget 都是這樣的:

復(fù)制代碼

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj package Microsoft.AspNetCore.All --version 2.1.2

在上面的示例中,使用值為“2.1.2”的“–version”標(biāo)志將修復(fù)對該版本的引用,而不僅僅是使用從 Nuget 提要中找到的最新版本。

為了再次檢查我們的 Nuget 依賴問題是否已經(jīng)解決,我們可以使用下面的命令進(jìn)行檢查,它比重新編譯所有東西要更快:

復(fù)制代碼

dotnet clean && dotnet restore DotNetCliArticle.sln

作為一個(gè)有經(jīng)驗(yàn)的.NET 開發(fā)人員,我非常擔(dān)心臨時(shí) /obj 和 /bin 文件夾中殘留的文件。因此,我在 Visual Studio 中使用“Clean Solution”命令,以防我試圖改變引用的時(shí)候落下些什么。從命令行執(zhí)行“dotnet clean”命令是完全相同的操作。

同樣,針對眾所周知的 Nuget 依賴問題,“dotnet restore”命令在解決方案中都試著去解決了。在這種情況下,使用“dotnet restore”可以讓我們快速發(fā)現(xiàn)任何潛在的沖突或丟失的 Nuget 引用,而無需進(jìn)行完整的編譯,我在自己的工作中主要就采用該命令。在最新版本的 dotnet cli 中,在調(diào)用“dotnet build/test/pack/etc”時(shí),會自動(dòng)為您完成 Nuget 解析 (該行為可以用標(biāo)記覆蓋),這將首先需要 Nuget。

我們調(diào)用的“dotnet restore DotNetCliArticle.sln”干凈利落地運(yùn)行完畢,沒有錯(cuò)誤,所以我們終于可以準(zhǔn)備編寫一些代碼了。讓我們打開您選擇的 C# 編輯器,向 HeyWorld 添加一個(gè)代碼文件。測試項(xiàng)目包含一個(gè)非常簡單的 HTTP 協(xié)議測試,它將指定我們希望從新的 HeyWorld 應(yīng)用程序中的“GET: /”路由獲得的行為:

復(fù)制代碼

using System.Threading.Tasks;using Alba;using Xunit;namespace HeyWorld.Tests{ public class verify_the_endpoint { [Fact] public async Task check_it_out() { using (var system = SystemUnderTest.ForStartup<Startup>()) { await system.Scenario(s => { s.Get.Url("/"); s.ContentShouldBe("Hey, world."); s.ContentTypeShouldBe("text/plain; charset=utf-8"); }); } } }}

結(jié)果文件應(yīng)該保存在具有適當(dāng)名稱 (如 verify_the_endpoints.cs) 的 HeyWorld.Tests 目錄。

在沒有深入了解 Alba 機(jī)制前,我們的新 HeyWorld 應(yīng)用的首頁路由應(yīng)該寫出“Hey, world”。雖然我們還沒有在 HeyWorld 應(yīng)用中編寫任何實(shí)際的代碼,但是我們?nèi)匀豢梢赃\(yùn)行這個(gè)測試,看看它能夠連接正確,還是因?yàn)槟承袄硭?dāng)然的理由”而失敗。

回到命令行,我可以使用以下命令運(yùn)行測試項(xiàng)目中的所有測試:

復(fù)制代碼

dotnet test HeyWorld.Tests/HeyWorld.Tests.csproj

我們的一個(gè)測試會失敗,因?yàn)檫€沒有實(shí)現(xiàn)任何東西,它給了我們這樣的輸出:

復(fù)制代碼

Build started, please wait...Build completed.Test run for /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/bin/Debug/netcoreapp2.1/HeyWorld.Tests.dll(.NETCoreApp,Version=v2.1)Microsoft (R) Test Execution Command Line Tool Version 15.7.0Copyright (c) Microsoft Corporation. All rights reserved.Starting test execution, please wait...Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.Test Run Successful.Test execution time: 2.4565 Seconds

為了把輸出求和,執(zhí)行了一個(gè)測試,但是失敗了。我們還可以看到標(biāo)準(zhǔn)的 xUnit 輸出,它提供了一些關(guān)于測試失敗原因的信息。這里需要注意的是,“dotnet test”命令將返回一個(gè)退出代碼,如果所有測試都通過,則返回 0,表示成功;如果任何測試失敗,則返回一個(gè)非零退出代碼,表示失敗。這對于持續(xù)集成 (CI) 腳本非常重要,大多數(shù) CI 工具使用任何命令的退出代碼來確定構(gòu)建何時(shí)失敗。

我認(rèn)為上面的測試之所以失敗是因?yàn)椤袄硭?dāng)然的原因”,這意味著測試工具似乎能夠引導(dǎo)真正的應(yīng)用程序,我希望得到 404 響應(yīng),因?yàn)檫€沒有編寫任何代碼。接下來,讓我們?yōu)轭A(yù)期的行為實(shí)現(xiàn)一個(gè) MVC Core 端點(diǎn):

復(fù)制代碼

public class HomeController : Controller{ [HttpGet("/")] public string SayHey() { return "Hey, world!"; }}

(注意,前面的代碼應(yīng)該作為 HeyWorldstartup.cs 文件中的附加類添加)

再次回到命令行,讓我們運(yùn)行前面的“dotnet test HeyWorld.Tests/HeyWorld.Tests.csproj”命令,希望看到這樣的結(jié)果:

復(fù)制代碼

Build started, please wait...Build completed.Test run for /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/bin/Debug/netcoreapp2.1/HeyWorld.Tests.dll(.NETCoreApp,Version=v2.1)Microsoft (R) Test Execution Command Line Tool Version 15.7.0Copyright (c) Microsoft Corporation. All rights reserved.Starting test execution, please wait...Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.Test Run Successful.Test execution time: 2.4565 Seconds

好了,現(xiàn)在測試通過了,讓我們運(yùn)行實(shí)際的應(yīng)用程序。由于“dotnet new webapi”模板使用進(jìn)程內(nèi)的 in-process Kestrel web server 來處理 HTTP 請求,所以要運(yùn)行新的 HeyWorld 應(yīng)用程序,我們唯一需要做的一件事就是從命令行使用以下命令啟動(dòng)它:

復(fù)制代碼

dotnet run --project HeyWorld/HeyWorld.csproj

運(yùn)行上面的命令應(yīng)該會得到如下輸出:

復(fù)制代碼

Using launch settings from HeyWorld/Properties/launchSettings.json...: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]User profile is available. Using '/Users/jeremydmiller/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.Hosting environment: DevelopmentContent root path: /Users/jeremydmiller/code/DotNetCliArticle/HeyWorldNow listening on: https://localhost:5001Now listening on: http://localhost:5000Application started. Press Ctrl C to shut down.

要測試我們現(xiàn)在正在運(yùn)行的新應(yīng)用程序,只需在瀏覽器中導(dǎo)航如下:Netcore【】(圖2)

處理 HTTPS 設(shè)置超出了本文的范圍。

請?jiān)俅巫⒁猓壹僭O(shè)所有命令都是在將當(dāng)前目錄設(shè)置為解決方案根文件夾的情況下執(zhí)行的。如果當(dāng)前目錄是一個(gè)項(xiàng)目目錄,并且只有一個(gè) *.csproj。那么,您只需在該目錄下鍵入“dotnet run”即可。現(xiàn)在我們已經(jīng)有了一個(gè)經(jīng)過測試的 web api 應(yīng)用程序,接下來讓我們將 HeyWorld 放到 Docker 鏡像中。使用 the standard template for dockerizing a .NET Core application,我們將向 HeyWorld 項(xiàng)目添加一個(gè) Dockerfile,內(nèi)容如下:

復(fù)制代碼

FROM microsoft/dotnet:sdk AS build-envWORKDIR /appCopy csproj and restore as distinct layersCOPY *.csproj ./RUN dotnet restoreCopy everything else and buildCOPY . ./RUN dotnet publish -c Release -o outBuild runtime imageFROM microsoft/dotnet:aspnetcore-runtimeWORKDIR /appCOPY --from=build-env /app/out .ENTRYPOINT ["dotnet", "HeyWorld.dll"]

(注意,前面的文本應(yīng)該保存到項(xiàng)目目錄中名為 Dockerfile 的文本文件中——在本例中是 HeyWorldDockerfile)。

因?yàn)檫@篇文章僅僅是關(guān)于 dotnet cli 的,我只想關(guān)注 Dockerfile 中它的兩種用法:

1.“dotnet restore”–正如我們在上面學(xué)到的,這個(gè)命令將解決應(yīng)用程序的任何 Nuget 依賴關(guān)系。

2.“dotnet publish -c Release -o out”–“dotnet publish”命令將構(gòu)建指定的項(xiàng)目,并將組成應(yīng)用程序的所有文件復(fù)制到給定位置。在我們的例子中,“dotnet publish”將為 HeyWorld 本身復(fù)制已編譯的程序集、從 Nuget 依賴項(xiàng)引用的所有程序集、配置文件以及 csproj 文件中引用的任何文件。

請注意,在上面的用法中,我們必須通過使用“-c Release”標(biāo)志明確地告知“dotnet publish”用“Release”配置編譯。那些用于編碼的 dotnet cli 命令 (例如“build”、“publish”、“pack”)如果沒有指定,將以 “Debug”為默認(rèn)值。注意這種行為,如果要發(fā)布用于生產(chǎn)的 Nuget 或應(yīng)用程序,請記住指定“-c Release”或“-configuration Release”。別怪我沒提醒你。

為了完成整個(gè)周期,我們現(xiàn)在可以使用以下命令通過 Docker 構(gòu)建和部署我們的小 HeyWorld 應(yīng)用程序:

復(fù)制代碼

docker build -t heyworld .docker run -d -p 8080:80 --name myapp heyworld

第一個(gè)命令為我們的應(yīng)用程序“heyworld”構(gòu)建并本地發(fā)布 Docker 鏡像。第二個(gè)命令實(shí)際上作為一個(gè)名為“myapp”的 Docker 容器運(yùn)行我們的應(yīng)用程序。您可以打開瀏覽器訪問“http://localhost:8080”予以驗(yàn)證。

總結(jié)

dotnet cli 使得基于. NET 項(xiàng)目的自動(dòng)化和腳本編寫變得非常簡單,尤其是與十多年前的.NET 技術(shù)相比。在許多情況下,您甚至可能會避開任何基于任務(wù)的構(gòu)建腳本工具 (Cake、Fake、Rake、Psake 等),而選擇只委托給 dotnet cli 的簡單 shell 腳本。此外,dotnet cli 可擴(kuò)展性模型可以很容易地將外部.NET 授權(quán)的命令行應(yīng)用程序通過 Nuget 分布到自動(dòng)構(gòu)建程序中。

關(guān)于作者杰里米·米勒 (Jeremy Miller)在密蘇里州一個(gè)農(nóng)場社區(qū)長大,那里有一群“特別”的人,名叫“樹蔭技工”。通常,他們不是世界上最有名望的人,但他們有解決機(jī)械問題的訣竅,而且做事魯莽無畏。如果你發(fā)現(xiàn)從一輛停在街區(qū)的通勤車下伸出來兩條腿,那他想必就是名修理工了,他的周圍是一些骨架車,堆擠在他那長滿灌木、堆滿垃圾的院子里。你看到的被遺棄在他周圍的打漿機(jī)并不是沒用的,他們是素材。他會零零碎碎地進(jìn)行些小調(diào)整,然后根據(jù)你的需要想出一個(gè)創(chuàng)造性的解決方案。盡管名聲一般,但一個(gè)樹蔭技工知道如何讓東西運(yùn)行。雖然米勒沒有任何特殊的機(jī)械能力 (盡管他擁有機(jī)械工程學(xué)位),但他喜歡把自己當(dāng)成一個(gè)像樹蔭技工似的開發(fā)人員。他的硬盤上肯定到處都是廢棄的開源項(xiàng)目碎片。隨著.NET Core 2.0 的發(fā)布,微軟擁有了通用、模塊化、跨平臺和開源平臺的下一個(gè)主要版本,該版本最初于 2016 年發(fā)布。.NET Core 已經(jīng)創(chuàng)建了許多 API,這些 API 在.NET 框架的當(dāng)前版本中是可用的。它最初是為了下一代 ASP.NET 解決方案創(chuàng)建的,但現(xiàn)在是許多其他場景的驅(qū)動(dòng)和基礎(chǔ),包括物聯(lián)網(wǎng)、云和下一代移動(dòng)解決方案。在關(guān)于.NET Core 的第二個(gè)系列的文章中,我們將進(jìn)一步探討.NET Core 的優(yōu)點(diǎn),以及它如何不僅有益于傳統(tǒng)的.NET 開發(fā)人員,也有益于所有需要為市場提供強(qiáng)健的、高效的和經(jīng)濟(jì)的解決方案的技術(shù)人員。

主站蜘蛛池模板: 色爱区综合五月激情 | 欧美二区在线观看 | 国精产品一区二区三区 | 日韩专区在线 | 国产精品久久久久久久久久99 | 超碰最新在线 | 亚洲男人的天堂网站 | 日韩1区 | 亚洲精品欧美视频 | 日韩一区二区三区在线视频 | 免费国产一区二区 | 久久久久久网站 | 91精品一区二区三区久久久久 | 国产精品毛片 | 亚洲视频综合 | 91在线导航 | 日韩视频在线播放 | 国产精品第2页 | 国产精品无码永久免费888 | 欧美一区久久 | 麻豆精品一区二区 | 欧美日韩国产精品一区 | 国产中文字幕在线 | 亚洲成人一区 | av在线天堂 | av一级久久 | 色一情一乱一伦一区二区三区 | 日韩精品一区二区三区四区视频 | 亚洲成人久久久 | 日韩一区中文字幕 | 在线视频 91 | 国产一区不卡 | 九九久久精品视频 | 欧美成人一区二区三区 | 欧美日韩在线精品 | 欧美久久精品 | 久久久久久久久久久久久久av | 久久精品成人 | 免费一区二区三区 | 91免费版在线观看 | 亚洲tv久久爽久久爽 |