How do I connect to Nuget online repository using Nuget API? - nuget

I am trying to connect to Nuget Online repository using a HTTP URI. I am using PackageManager object and supplying it with DataServicePackageRepository object in the constructor. It does not seem to fetch the list. What I might be doing wrong ?
Should I use a different Repository class?
Here is my Package Manager initializer code
var remoteRepo = new NuGet.DataServicePackageRepository(new Uri("http://myserver/myrepo/nuget"));
PackageManager pkgMan = new PackageManager(remoteRepo, #"C:\Path\To\LocalRepoPath");

If you just want the list of packages you do not need to use the DataServicePackageRepository or the PackageManager directly. You can just use the PackageRepositoryFactory and the IPackageRepository.GetPackages() method.
The code below returns the top 10 packages ordered by the most downloaded. This is similar to what Visual Studio returns in the Manage Packages dialog.
string url = "https://www.nuget.org/api/v2/";
IPackageRepository repo = PackageRepositoryFactory.Default.CreateRepository(url);
var packages = repo
.GetPackages()
.Where(p => p.IsLatestVersion)
.OrderByDescending(p => p.DownloadCount)
.Take(10);
foreach (IPackage package in packages) {
Console.WriteLine(package);
}

Related

Blazor component - Failed to fetch dynamically imported module when packed in nuget

I created a blazor component that loads an isolated js interop file (target framework .Net 7)
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var dotNetObjRef = DotNetObjectReference.Create(this);
_routeMapModule = await JsRuntime.InvokeAsync<IJSObjectReference>("import", "./_content/MyComp/MyJs.js");
await _routeMapModule.InvokeVoidAsync("CompInit", _elRef, dotNetObjRef);
}
}
MyComp is the ProjectName so the path to get the file is "./_content/MyComp/MyJs.js".
As long as I use this component as a project reference (blazor server), everything works fine.
But as soon as I package this component in a Nuget (azure pipeline), and reference it in the project (instead of a project reference), I get "Failed to load resource: the server responded with a status of 404 () / Failed to fetch dynamically imported module when packed in nuget".
When I check the nuget in my local nuget storage (unziping it), I find the js file in the root but if I search it in the main app generated bin, it is not there.
Is there a specific parameter for the Nuget deployment ?
I tried to create the nuget directly from visual studio and/or to modify the generation parameters on Azure.
The final nuget contains the js resource file but it does not seem to be published in the main project (the one that references the nuget).
Also tried to move the file referenced in wwwroot but same problem.
What's weird is that everything works fine as long as I'm in "project reference" mode but the path "./_content/MyComp/MyJs.js" doesn't seem to follow when it's packaged in a nuget.
Any idea ?
Main Blazor App: https://jmpnet.visualstudio.com/JmpNetPublic/_git/MainBlazorApp
Blazor component App: https://jmpnet.visualstudio.com/JmpNetPublic/_git/MyComp
Nuget Feed for Blazor component App:
Name: JmpNetPublic
Source: https://jmpnet.pkgs.visualstudio.com/JmpNetPublic/_packaging/JmpNetPublic/nuget/v3/index.json
Update (29.12.2022):
I have no problem to load the module as long as I stay in project reference (with or without lazy loading).
The problem happens only when the component is packaged in Nuget.
When deploying the Nuget, the js file does not follow.
It seems to be mostly a Nuget packaging issue (via Azure) but I can't find the settings that force the deployment of the js file.
OK. The problem was with the Azure Pipeline configuration.
if I generate the nuget directly on my workstation and push it, everything works fine.
But as soon as I did the generation using an Azure pipeline, the js file was no longer deployed.
I was actually using YAML Nuget commands (targeting .net framework) with a .Net Core project.
Now that I use ".Net Core" YAML , everything works correctly.
Lazy load the module:
public partial class TestComp : ComponentBase, IAsyncDisposable
{
[Inject]
private IJSRuntime JsRuntime { get; set; }
private readonly Lazy<Task<IJSObjectReference>> moduleTask;
[Parameter]
public string? Message { get; set; }
public TestComp()
{
moduleTask = new(() => JsRuntime!.InvokeAsync<IJSObjectReference>(
identifier: "import",
args: "./_content/MyComp/MyScript.js")
.AsTask());
}
private async Task Click()
{
var module = await moduleTask.Value;
Message += "...click";
await module.InvokeAsync<string>("popup", Message);
}
public async ValueTask DisposeAsync()
{
if (moduleTask.IsValueCreated)
{
var module = await moduleTask.Value;
await module.DisposeAsync();
}
}
}
Note: I am assuming MyScript.js is in the wwwroot folder of the MyComp project which is the NuGet package.

using Unity.Plastic.Newtonsoft.Json not found in Rider

I'm trying to use:
using Unity.Plastic.Newtonsoft.Json
public static List<Level> GetLevels()
{
var asset = Resources.Load<TextAsset>("levels.json".Replace(".json", ""));
return JsonConvert.DeserializeObject<List<Level>>(asset.text);
}
and JsonConvert is in red.
and Plastic is showing in red. It says cannot resolve symbol Plastic.
Any ideas?
EDIT: I did install Newtonsoft.Json version 13 as assembly. No luck.
EDIT: using Newtonsoft.Json; also red.
Ok after some digging:
Apparently updated unity project which wiped out the dependency that was added via package manager > add package from git URL
Unity forgot a documented change for this. So, the answer:
Package Manager Window > Add Package from GIT URL > com.unity.nuget.newtonsoft-json
And instead of using using Unity.Plastic.Newtonsoft.Json
use using Newtonsoft.Json;
NOTE: On an older project where this was added manually, Newtonsoft Json wasn't showing up in the package manager > Packages: In Project until I went to the Cog Wheel > Checked Show Dependencies.

cakebuild: How to specify license in DotNetCorePack?

I try to specify the license for a nuget package in a cake script.
The following does not work - it doesn't put any license in the nuget package, and I can't find any documentation how to properly specify it:
var msbuildsettings = new DotNetCoreMSBuildSettings();
msbuildsettings = msbuildsettings.WithProperty("PackageLicenseExpression", "'LGPL-2.0-or-later'");
var settings = new DotNetCorePackSettings
{
MSBuildSettings = msbuildsettings,
Configuration = "Release",
OutputDirectory = "BuildOutput/NugetPackages",
NoBuild = true,
};
foreach(var gassembly in list)
DotNetCorePack(gassembly.Csproj, settings);
I am not sure this is a Cake issue. Cake just wraps existing tools.
The NuGet docs tell you how to specify package meta data. You generally want to specify metadata in the csproj when using dotnet pack
https://learn.microsoft.com/en-us/dotnet/core/tools/csproj#nuget-metadata-properties
The value of the PackageLicenseExpression property should be a valid SPDX license identifier string without any apostrophes.
Just remove the apostrophes and your code should work fine and add the license expression to the NuGet package.
msbuildsettings = msbuildsettings.WithProperty("PackageLicenseExpression", "LGPL-2.0-or-later");

how to call Package Manager Console and execute Find-Package in visual studio extension

I'm developing a visual studio extension(vsix).
Now, I want to get a nuget package latest version. I only found one way by using Package Manager Console, dotnet CLI still not support search command.
So, how can I call Package Manager Console and execute Find-Package command, or is there another way can get package latest version from specific package source server.
Have you tried the way in below doc or not?
https://learn.microsoft.com/en-us/nuget/guides/api/query-for-all-published-packages
I built a simple VSIX with customer Command item, and it could use below code to perform search packages from NuGet(need to install Nuget.PackageManagement into your VSIX project first).
List<Lazy<INuGetResourceProvider>> providers = new List<Lazy<INuGetResourceProvider>>();
providers.AddRange(Repository.Provider.GetCoreV3()); // Add v3 API support
//providers.AddRange(Repository.Provider.GetCoreV2()); // Add v2 API support
PackageSource packageSource = new PackageSource("https://api.nuget.org/v3/index.json");
SourceRepository sourceRepository = new SourceRepository(packageSource, providers);
PackageMetadataResource packageMetadataResource = await sourceRepository.GetResourceAsync<PackageMetadataResource>();
IEnumerable<IPackageSearchMetadata> searchMetadata = await packageMetadataResource.GetMetadataAsync("JSON.net", true, true, null, NuGet.Common.NullLogger.Instance, CancellationToken.None);
var a= searchMetadata.ToString();

Loading a NuGet assembly in T4 Template

I need to reference a Type in one of the assemblies referenced by the project containing my Visual Studio T4 template. However, the referenced assembly is installed from a NuGet package. As that Nuget reference evolves, so will the path that NuGet places it in within my solution's packages folder. For example, suppose my NuGet package is:
Facade.Contract.1.0.1-alpha
Then the relative path to it from my project is:
..\packages\Facade.Contract.1.0.1-alpha\lib\net4\Facade.Contract.dll
If the prerelease is updated to beta, that path will change. When the package is released, the path will change. And every time the path changes, the assembly line in my *.tt file is out of date:
<## assembly name="..\packages\Facade.Contract.1.0.1-alpha\lib\net4\Facade.Contract.dll" #>
I don't think there's a way to accomplish this directly with the assembly directive; however, I'm open to some crazy ideas. Could I load the assembly myself into the current, or a subordinate or reflection-only AppDomain?
I think I could, but I'm not sure how to go about dynamically discovering the path to the referenced assembly in the project's references using T4 logic.
Any ideas?
I've found a solution using VSLangProject as suggested by this article: http://t4-editor.tangible-engineering.com/blog/add-references-to-visual-studio-project-from-t4-template.html
Given a string serviceContractReferenceAssembly a to identify the name of the reference assembly in my containing project, and serviceContractReferenceType to identify the type within that assembly, the following worked:
var templateItem = dte.Solution.FindProjectItem(this.Host.TemplateFile);
var project = templateItem.ContainingProject;
var vsProject = project.Object as VSLangProj.VSProject;
foreach(var referenceObj in vsProject.References)
{
var reference = (VSLangProj.Reference)referenceObj;
if(reference.Name != serviceContractReferenceAssembly) continue;
var serviceContractAssembly = Assembly.LoadFile(reference.Path);
var serviceContractType = serviceContractAssembly.GetType(serviceContractReferenceType);
// Do something with it here
}
The Nuget team has made an extension available that allows you some control over the packages in a solution/project. So if you have control over the environment and can be sure everyone has this installed you might be able to search for the installed packages and then dynamically load them during your T4 execution. Since these Nuget assemblies are already complied and not part of your solution/project I would think using the standard Assembly.Load would work but you would need to test that.