18

First off, of all the NuGet code, I'm trying to figure out which one to reference.

The main question is, given a NuGet package name, is there a programmatic way to retrieve the versions from the NuGet feed and also the latest version for general consumption?

For example, given a package name of ILMerge, it would be nice to get the latest package version of 2.13.307.

// Pseudo code, makes a lot of assumptions about NuGet programmatic interfaces
PackageRef currentVersion = nugetlib.getpackageinfo(args[0]);
Console.WriteLine("Package Id: '{0}':", pkg.Id);
Console.WriteLine("  Current version: {0}", pkg.Version);
Console.WriteLine("  Available versions: {0}", String.Join(",",pkg.Versions.Select(_=>_)));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
enorl76
  • 2,562
  • 1
  • 25
  • 38
  • Something that can help you, maybe? http://blog.diniscruz.com/2013/05/retrieving-nuget-package.html – David Brabant Oct 31 '14 at 15:14
  • @DavidBrabant I think the page your link was pointing to got sold. Now it triggers a lot of redirects and leads to shops etc. – Prolog Jun 17 '22 at 11:56

4 Answers4

11

Use the NuGet core package:

string packageID = "ILMerge";

// Connect to the official package repository
IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository("https://packages.nuget.org/api/v2");
var version =repo.FindPackagesById(packageID).Max(p=>p.Version);

Reference: Play with Packages, programmatically!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Damith
  • 62,401
  • 13
  • 102
  • 153
  • 1
    Note that NuGet.Core is now deprecated - it's recommended to instead use [NuGet.Protocol](https://www.nuget.org/packages/NuGet.Protocol/) instead ([documentation](https://learn.microsoft.com/en-us/nuget/reference/nuget-client-sdk)). – Wai Ha Lee Mar 23 '22 at 10:23
  • It's nice to see that `Version` implements `IComparable` so that it can be retrieved directly. – Shimmy Weitzhandler Dec 27 '22 at 20:33
3

There exist a quite nice NuGet API to accomplish both.

a) Retrieving the NuGet package versions (for the Newtonsoft.Json package in following example):

GET https://api.nuget.org/v3-flatcontainer/Newtonsoft.Json/index.json

b) Downloading a certain version of the NuGet package - e.g.

GET https://api.nuget.org/v3-flatcontainer/utf8json/1.3.7/utf8json.1.3.7.nupkg

Please try to copy the URL to the browser and you could see the results of the examples...

To get more information about API, please visit the Package Content

The following code example could read the versions of a package (using the Microsoft.AspNet.WebApi.Client NuGet package which provides HttpContent's ReadAsAsync<T> extension for parsing the JSON result to an appropriate class - the VersionsResponse in this example)

using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace GetNuGetVer
{
    class VersionsResponse
    {
        public string[] Versions { get; set; }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            var packageName = "Enums.NET";
            var url = $"https://api.nuget.org/v3-flatcontainer/{packageName}/index.json";
            var httpClient = new HttpClient();
            var response = await httpClient.GetAsync(url);
            var versionsResponse = await response.Content.ReadAsAsync<VersionsResponse>();
            var lastVersion = versionsResponse.Versions[^1]; //(length-1)
            // And so on ..
        }
    }
}

To get rid of Microsoft.AspNet.WebApi.Client (with dependency to Newtonsoft.Json), System.Text.Json can be used out of the box (since .NET Core 3.0) with code changes as follows:

        using System.Text.Json;
        ...
        var response = await httpClient.GetAsync(url);
        var versionsResponseBytes = await response.Content.ReadAsByteArrayAsync();
        var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
        var versionsResponse = JsonSerializer.Deserialize<VersionsResponse>(versionsResponseBytes, options);
        var lastVersion = versionsResponse.Versions[^1]; //(length-1)

or just a different JSON parser based on your own preferences.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rychlmoj
  • 385
  • 1
  • 3
  • 14
  • The https://michaelscodingspot.com/the-battle-of-c-to-json-serializers-in-net-core-3/ could help choosing the right JSON parser .. – rychlmoj Feb 21 '20 at 21:43
  • 1
    That url is not working for me and returns ``` BlobNotFound The specified blob does not exist. RequestId:a42c4f2e-001e-0001-6f0e-c1e279000000 Time:2022-09-05T10:04:06.0211970Z ``` – Ramon Smits Sep 05 '22 at 10:04
2

As described on NuGet2, Nuget.Core is for version 2 of NuGet.

Version 3 of the NuGet client library has moved to Nuget.Client. See the NuGet API v3 documentation for more information.

NuGet Client SDK

Sielu
  • 1,070
  • 14
  • 19
0

The answers in this thread either no longer work, return only partial results, or have been deprecated.

I found a working solution, which is to use the newer NuGet API version:

GET https://api.nuget.org/v3/registration5-semver1/{your package name here, lowercase}/index.json

For example to find the package information for the RavenDB.Identity package, I'd call it like this:

GET https://api.nuget.org/v3/registration5-semver1/ravendb.identity/index.json

Note that the package name must be converted to lowercase, otherwise you'll get an error.

The actual latest package version number can be fetched like this:

let results = await fetch("https://api.nuget.org/v3/registration5-semver1/ravendb.identity/index.json");
let json = await results.json();
let package = json.items[0];
let latestPackage = package.items[package.items.length - 1];
let version = latestPackage.catalogEntry.version; // returns a string like "8.0.7"

Here's a working JS snippet that shows the latest version of a package:

async function fetchLatestVersion() {
   let results = await fetch("https://api.nuget.org/v3/registration5-semver1/ravendb.identity/index.json");
   let json = await results.json();
   let package = json.items[0];
   let latestPackage = package.items[package.items.length - 1];
   let version = latestPackage.catalogEntry.version;

   document.querySelector("#results").innerText = `The latest version of the RavenDB.Identity package is ${version}`;
}

setTimeout(() => fetchLatestVersion(), 1000);
<div id="results">Fetching results...</div>
Judah Gabriel Himango
  • 58,906
  • 38
  • 158
  • 212