1. 程式人生 > >使用WebAPI、.NET Core CLI、NuGet CLI操作Nuget源

使用WebAPI、.NET Core CLI、NuGet CLI操作Nuget源

最近專案上元資料開發,準備使用nuget包進行封裝,所以對nuget源進行了一些研究主要包含以下三種。

WebAPI

官方文件說明上介紹nuget源提供的WebAPI是遵循Odata規範的,但是通過驗證發現存在很多問題,大多數api介面只適應於nuget官方倉庫,以下是經過測試可用的介面。如果有興趣可以發掘更多,詳情參考:https://docs.microsoft.com/zh-cn/nuget/api/overview

1. 獲取指定包資訊:

http://localhost/nuget/nuget/Packages(Id='Inspur.Ecp.Caf.Context',Version='1.0.0-alpha-1806300128')

2. 下載指定包資訊:

http://localhost/nuget/nuget/Packages(Id='Inspur.Ecp.Caf.Context',Version='1.0.0-alpha-1806300128')/Download

3. 查詢一個nuget包所有版本資訊:

http://localhost/nuget/nuget/Packages?$filter=Id eq 'Inspur.Ecp.Caf.Caching'

4. 關鍵字搜尋(例如caf):

這個地方要說一樣,最早以為nuget提供的api介面是遵循Odata原則的,所以把Packages作為資源研究各種操作,最後百般嘗試均已失敗告終(感覺應該姿勢不對)。最後無可奈何,修改了VS中的nuget.config配置檔案,然後在輸出視窗得到了這個api。searchTerm是搜尋關鍵字,可以為空(即查詢所有)。skip和top負責分頁載入,其他屬性不重要就不一一解釋了

http://localhost/nuget/Search()?$filter=IsAbsoluteLatestVersion&searchTerm='caf'&targetFramework=''&includePrerelease=true&$skip=0&$top=26&semVerLevel=2.0.0

5. 上傳nuget包(Put方法):

具體如何使用put方法上傳檔案,可以參考上篇

http://localhost/nuget/nuget/Packages

6. 查詢所有包數量(每個包取最新版本):

因為前端展示需要分頁,所以用到了這個方法

http://localhost/nuget/nuget/Packages/$count?$filter=IsAbsoluteLatestVersion

API介面獲取到的返回資訊示例

<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://localhost/nuget/nuget" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
    <id>http://localhost/nuget/nuget/Packages(Id='Inspur.Ecp.Caf.Caching',Version='1.0.0-alpha-1805240806')</id>
    <category term="NuGet.Server.Core.DataServices.ODataPackage" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <link rel="edit" href="http://localhost/nuget/nuget/Packages(Id='Inspur.Ecp.Caf.Caching',Version='1.0.0-alpha-1805240806')" />
    <link rel="self" href="http://localhost/nuget/nuget/Packages(Id='Inspur.Ecp.Caf.Caching',Version='1.0.0-alpha-1805240806')" />
    <title type="text">Inspur.Ecp.Caf.Caching</title>
    <published>2018-09-22T05:38:46Z</published>
    <updated>2018-09-22T05:38:46Z</updated>
    <author>
        <name>Inspur.Ecp.Caf.Caching</name>
    </author>
    <m:action metadata="http://localhost/nuget/nuget/$metadata#Container.Download" title="Download" target="http://localhost/nuget/nuget/Packages(Id='Inspur.Ecp.Caf.Caching',Version='1.0.0-alpha-1805240806')/Download" />
    <content type="application/zip" src="http://localhost/nuget/nuget/Packages(Id='Inspur.Ecp.Caf.Caching',Version='1.0.0-alpha-1805240806')/Download" />
    <m:properties>
        <d:Id>Inspur.Ecp.Caf.Caching</d:Id>
        <d:Version>1.0.0-alpha-1805240806</d:Version>
        <d:NormalizedVersion>1.0.0-alpha-1805240806</d:NormalizedVersion>
        <d:IsPrerelease m:type="Edm.Boolean">true</d:IsPrerelease>
        <d:Title m:null="true" />
        <d:Authors>Inspur.Ecp.Caf.Caching</d:Authors>
        <d:Owners>Inspur.Ecp.Caf.Caching</d:Owners>
        <d:IconUrl m:null="true" />
        <d:LicenseUrl m:null="true" />
        <d:ProjectUrl m:null="true" />
        <d:DownloadCount m:type="Edm.Int32">-1</d:DownloadCount>
        <d:RequireLicenseAcceptance m:type="Edm.Boolean">false</d:RequireLicenseAcceptance>
        <d:DevelopmentDependency m:type="Edm.Boolean">false</d:DevelopmentDependency>
        <d:Description>Package Description</d:Description>
        <d:Summary m:null="true" />
        <d:ReleaseNotes m:null="true" />
        <d:Published m:type="Edm.DateTime">2018-09-22T05:38:46.9446845Z</d:Published>
        <d:LastUpdated m:type="Edm.DateTime">2018-09-22T05:38:46.9446845Z</d:LastUpdated>
        <d:Dependencies>Inspur.Ecp.Caf.Common:1.0.0-alpha-1805160358:netstandard2.0|Inspur.Ecp.Caf.Configuration:1.0.0-alpha-1805180837:netstandard2.0|Inspur.Ecp.Caf.Exception:1.0.0-alpha-1805190142:netstandard2.0|Microsoft.Extensions.Caching.Memory:2.0.2:netstandard2.0|Microsoft.Extensions.Caching.Redis:2.0.2:netstandard2.0</d:Dependencies>
        <d:PackageHash>cx61NZsnDXHcx37hhC2Py51QJxO6vVX51Rciwqzr6tB0oFlAClqd+L4bgpG9uCCBjq4XhV6iLc1tSYrPXgjCcg==</d:PackageHash>
        <d:PackageHashAlgorithm>SHA512</d:PackageHashAlgorithm>
        <d:PackageSize m:type="Edm.Int64">14072</d:PackageSize>
        <d:Copyright m:null="true" />
        <d:Tags m:null="true" />
        <d:IsAbsoluteLatestVersion m:type="Edm.Boolean">false</d:IsAbsoluteLatestVersion>
        <d:IsLatestVersion m:type="Edm.Boolean">false</d:IsLatestVersion>
        <d:Listed m:type="Edm.Boolean">true</d:Listed>
        <d:VersionDownloadCount m:type="Edm.Int32">-1</d:VersionDownloadCount>
        <d:MinClientVersion m:null="true" />
        <d:Language m:null="true" />
    </m:properties>
</entry>

解析程式碼示例

對於返回結果,我們只關心nuget包的名稱和版本。解析可以有多種形式,就是簡單的xml讀取就可以,這裡只是一個簡單的例子。

        private List<string> ResolveXml(string xmlStr)
        {
            List<string> packlist = new List<string>();
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xmlStr);
            string json = Newtonsoft.Json.JsonConvert.SerializeXmlNode(doc);
            JObject jo = JObject.Parse(json);
            JArray array = (JArray)jo["feed"]["entry"];

            foreach (var jObject in array)
            {
                packlist.Add(jObject["title"]["#text"].ToString() + "," + jObject["m:properties"]["d:Version"].ToString());
            }

            return packlist;
        }

.NET Core CLI

雖然API介面滿足了大部分需求,但是將元資料檔案打成nuget包還是需要藉助其他CLI命令。由於專案本身是基於 .NET Core 2.1,自然首先想到的是使用dotnet相關命令。具體可以參考:https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet?tabs=netcore21

1. 新增包:

這個命令相當於下載nuget包,但是必須要有一個project,和程式碼繫結的太死,這也是dotnet命令的一個機制,使用的話需要慎重考慮。具體引數可以參考:https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-add-package

dotnet add F:\GSPCloud\onlineuser-core\src\StakeoutController package Microsoft.Azure.DocumentDB.Core -v 1.0.0 --package-directory D:\元資料

2. 生成包:

和前一個命令一樣,包的生成也需要依賴於project,雖然最後發現可以指定.nuspec檔案,但是依舊和程式碼工程繫結太死,侷限性很大。具體引數可以參考:https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-pack?tabs=netcore2x

dotnet pack .\StakeoutWebApi.csproj -o .\pack /p:PackageVersion=2.1.0;NuspecFile= .\test.nuspec

3. 上傳包:

這裡需要注意的一點就是-k引數,在nuget源中的配置中會有一個apikey,一般會記錄在nuget.config檔案中,用來進行認證。具體引數可以參考:https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-pack?tabs=netcore2x

https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-nuget-push?tabs=netcore21

說到這裡,再附上一段程式碼執行CMD命令的示例

            //建立一個ProcessStartInfo物件 使用系統shell 指定命令和引數 設定標準輸出
            var psi = new ProcessStartInfo("dotnet", str) { RedirectStandardOutput = true, CreateNoWindow = false };
            //啟動
            var proc = Process.Start(psi);
            using (var sr = proc.StandardOutput)
            {
                while (!sr.EndOfStream)
                {
                    //後期可以記錄日誌
                   Console.WriteLine(sr.ReadLine());
                }

                if (!proc.HasExited)
                {
                    proc.Kill();
                }
            }

NuGet CLI

經過交流論證,發現還是使用原生的NuGet CLI最方便,雖然需要提前在環境中安裝nuget.exe。這裡只列舉我們所需的三個,有興趣可以去官網檢視,具體可以參考:https://docs.microsoft.com/zh-cn/nuget/tools/nuget-exe-cli-reference?tdsourcetag=s_pctim_aiomsg

1. 新增包:

這裡面也可以指定-Source,引數說明:https://docs.microsoft.com/zh-cn/nuget/tools/cli-ref-install

nuget install Inspur.GS.scm.sd.salesorder.metadata -version 1.0.0 -ConfigFile C:\Users\liu_wei\Desktop\GSPCloud\NuGet.Config -OutputDirectory D:\

2. 生成包:

不在依賴於project,可以指定生成路徑,引數說明:https://docs.microsoft.com/zh-cn/nuget/tools/cli-ref-pack

nuget pack D:\test.nuspec -version 1.0.0 –OutputDirectory D:\

3. 上傳包:

這裡面-Source是必須的,-ConfigFile 指定配置檔案,裡面記錄了認證資訊等。引數說明:https://docs.microsoft.com/zh-cn/nuget/tools/cli-ref-push

nuget push D:\codes\inspur.ecp.caf.sqlmapping.1.0.0-alpha-1808231427.nupkg -Source http://localhost/nuget/nuget -ConfigFile C:\Users\liu_wei\Desktop\GSPCloud\NuGet.Config