Status: In Progress
Issue to track new feature work around enabling packages.config (PC) to PackageReference (PR) upgrader workflow.
Here is the link to the spec.
Feel free to comment below with your feedback.
Related issues
Overall Issue Description:
Likely Project System Issues
[x] ~https://devdiv.visualstudio.com/DevDiv/NuGet/_workitems/edit/567298 - Wildcard support in legacy project system~ Won't fix.
[ ] Internal bug 465204 - NuGet Build Tasks donāt put proper metadata on satellite assemblies (potentially a restore issue)
NuGet Migration Issues:
NuGet PC to PR Migration Tool Issues
VS Extensibility Team Issues
C++ Team Issues
WPF Project Compat Issues:
Clean up our own Repro to remove the need for install.ps1
Work with package owners (see related item# https://github.com/NuGet/Home/issues/5960)
Validation to improve ecosystem for new push/ingested packages
Package Reference experience issues
You might want to add https://github.com/NuGet/Home/issues/5894 to your list of issues to be fixed. Since NuGet contains WPF assets, this could bite you.
Done.
Thanks @AArnott.
As I understand it, 465204 is also a scenario that works with packages.config but not PackageReferences
roslyn 22095 is one that is stopping us from migrating. I had it as a nuget issue originally. If nuget could have a type of lib that ended up being output to bin but would be flagged as not having its API exposed to consuming projects, then it wouldn't be a problem.
@mungojam NuGet packages can already depend on another package without exposing the API from that package to their own consumer. I think that that problem is solved at the right place right now because, for example, if package A depends on package B, we might say the ideal situation is that package A hides package B from the compiler of the app project if and only if no APIs from package B are exposed from package A's API.
Let's take an example:
Package B defines public class Tree
and Package A derives from it: public class AppleTree : Tree
.
It is important then that anyone referencing Package A automatically get Package B's types so the compiler doesn't emit an error when using AppleTree
telling the user to add a reference to resolve Tree
as a base type. That would be a bad experience for Package A's consumer if using it was broken by default. Also, considering Package A's public API itself depends on Package B, package A cannot remove its dependency on Package B without it being a binary breaking change, so it's unlikely they would do that--at least not without a major version increment per semver.
But now consider Package A
only defines internal class AppleTree
(note it is internal). Package B is now an implementation detail of Package A. Now it is appropriate for Package A to specify B as a dependency in their nuspec, including the attribute to omit B as a reference to the compiler that builds the app. Now the app can't accidentally take a dependency on B without the app developer adding a PackageReference to B explicitly, thereby mitigating the problem you're calling out.
The issue that remains, I think, is that most packages out there today don't do due diligence to mark their dependencies carefully in this way. And even if a package author wanted to, it's not trivial to audit your public API for dependencies of this kind, nor to maintain that properly over time. So tooling to automatically discern between public dependencies and internal dependencies, and possibly automatically setting the appropriate package dependency metadata may be the best way to solve your problem in general.
@AArnott Thanks for reviewing it, you've summed it up perfectly. I may be missing a trick then, how do we specify that a particular dependency is only to be added as an internal dependency and not exposed to compiler further up the chain?
I agree that tooling would definitely solve it nicely if the nuget mechanism exists already.
@AArnott Is this the mechanism you are referring to, using contentFiles?
<contentFiles>
<file include="bin/Release/SomeInternalDependency.dll" buildAction="None" copyToOutput="true" flatten="true" />
</contentFiles>
I might see what happens with a wildcard in the include. Maybe we could do that for the packages we make and then add external dependencies explicitly in an exclude.. sounds yukky, but might work.
No, don't use contentFiles for this. When building your own package via csproj with PackageReference
items, you add an attribute like this (if this were package A):
<PackageReference Include="PackageB" Version="1.0" PrivateAssets="compile" />
This makes it so your own package A consumes and references package B in your compiler references, but folks consuming package A will not get package B in their assembly references.
Thanks, that does work, actually using "compile;contentfiles;analyzers;build" to keep the default behaviour of PrivateAssets for the other types.
So, I will raise a feature request for the tooling improvement that you suggested, recognising that it won't be an easy thing to implement.
By the way, I had tried PrivateAssets previously and hit various errors. Some my own doing (package name clash). Other issues I ran into have been raised as issues already against the project system I think. I had to keep closing VS 15.4 and deleting obj/bin/.vs folders for various changes to package references to work. I hope that is fixed soon as it is a blocker for us too.
Is it the case that #4491 should be included in this checklist?
@awesley https://github.com/NuGet/Home/issues/6285 is tracking that work and is included in the list in the OP.
I can't see this mentioned anywhere, but I assume this would work just as well from the CLI, right? Remember, not everyone uses Visual Studio these days š
@khellang
packages.config installation/uninstallation works correctly only in Visual Studio.
Unfortunately the migration will only work in VS due to that limitation.
Do we _really_ need a backup? In 2018? For source code? It's just one more annoying directory to delete before commit.
@IanMercer you would be surprised...
@IanMercer I think a lot of people (most?) already have backup folders ignored. It's even part of GitHub's .gitignore template for Visual Studio š
Is this gonna work for Asp.Net Website (WSP) projects? These projects have no csproj file and currently they have support for NuGet using a packages.config file.
If packages.config files are deprecated/removed in the feature, WSP projects have no story for using NuGet?
@JarnoNijboer currently, the migrator will not be enabled for website projects. But that does not mean that packages.config is going to be deprecated, it will continue to be supported until there is a clear path forward to move to PackageReference
while the migrator will be available in 15.7, some of the issues listed in the OP still need to be worked on. Moving this to 4.8
I ran it against one of my class library projects and it added a lot more than just the package reference stuff. It added entries for PublishUrl, Intall.., Update..,Application.., etc. It also added Bootstrap entries. This is way more than I wanted. Just replace the package references - why is it making non-package related changes as well.
From:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
...
</PropertyGroup>
To:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
...
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
And added this-
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.6.1">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.6.1 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
@CoolDadTx that definitely doesnāt sound right. Any chance you can give us a repro project or your list of packages in packages.config ?
@CoolDadTx I had a similar issue whenever I made changes to project file these tags were added.
The problem was, my project once had ClickOnce and after removing ClickOnce there were still some stuff left behind and it tried to add again all the removed ClickOnce tags.
My solution was to make sure all ClickOnce tags were removed and the tags stopped reappearing.
Maybe your cause is similar.
Do you know what element triggered ClickOnce because this was a class library project that had no references to ClickOnce at any point? The only element I see that might have been auto-added when the project was created was TargetFrameworkProfile.
@rohit21agrawal
Packages config:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AutoMapper" version="6.0.2" targetFramework="net461" />
<package id="EntityFramework" version="6.1.3" targetFramework="net452" />
<package id="Fsmb" version="2.0.1.0" targetFramework="net451" />
<package id="Fsmb.Apollo" version="5.0.17009.1" targetFramework="net461" />
<package id="Fsmb.Augusta" version="2.5.17177.1" targetFramework="net461" />
<package id="Fsmb.Augusta.Cdc" version="2.5.17052.1" targetFramework="net461" />
<package id="Fsmb.Augusta.EntityFramework" version="2.5.17177.1" targetFramework="net461" />
<package id="Fsmb.EnterpriseServices.Logging" version="3.0.17083.3" targetFramework="net461" />
<package id="Fsmb.EnterpriseServices.Reporting" version="1.0.14065.5" targetFramework="net452" />
</packages>
We have a private VSTS repo where most of the packages come from but the rest are in NuGet.
@CoolDadTx
oh, I might not be able to test this out if your packages are coming from a private VSTS repo.
can you try this:
1) Create a plain old packages.config based Class Library (Full .NET Framework). Check the project file.
2) Install the packages you listed above
3) Check the project file for any changes after installation.
4) Migrate from packages.config to PackageReference .
5) Look for any further changes.
If there is something confidential about your projects/packages that you can't share with us, I can work on getting a NDA so I can inspect where the migration is going wrong?
I tried a test scenario and couldn't replicate it. I wiped my changes from the original project and ran it again and it didn't do it this time. Strange, maybe some other extension was trying to do something as well. I'll consider this issue closed for now. Thanks.
thanks @CoolDadTx for verifying! If you do have any other feedback/issues with the migrator, please do share with us!
@rohit21agrawal, I do have one complaint but I suspect there is nothing you can do about it. When the migrator is moving packages it is auto-generating an app.config file if one does not exist. I suspect this is because it is trying to uninstall a package that had transforms (i.e. EntityFramework) but I'm only guessing here. Nevertheless every project that has the migration tool run on it (that didn't have an app.config before) now has an empty one that has to be deleted. I replicated this by creating a class library that was using EntityFramework but had no config (because it was a library).
@CoolDadTx installing EntityFramework to a packages.config based ClassLibrary actually ended up creating an app.config for me with the following content:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
@rohit21agrawal, correct. Now go to the project and delete the app.config file. Then go out to the file system and ensure it is gone. Save the project. Then run the package migration tool. Notice there is no app.config in the project but if you go out to the file system it has in fact created an empty app.config file. That config file will be pushed to Git if you happen to be using it.
I tried running the tool on one of my projects and VS crashes. I attached to it from another VS instance to see why and i'm seeing an exception thrown with the message "Illegal characters in path."
I can't figure out why this is happening.
This the stack trace:
mscorlib.dll!System.IO.Path.CheckInvalidPathChars(string path, bool checkAdditional) Unknown
mscorlib.dll!System.IO.Path.GetFileName(string path = "D:\\tfs\\Testvs17\\.\t\t") Unknown
Microsoft.TeamFoundation.Common.dll!Microsoft.TeamFoundation.Common.FileSpec.GetFullPath(string path = "D:\\tfs\\Testvs17\\.\t\t", bool checkForIllegalDollar = false) Unknown
> Microsoft.TeamFoundation.VersionControl.Client.dll!Microsoft.TeamFoundation.VersionControl.Client.Client.GetLocalWorkspace(string localPath, bool throwIfNotFound = false) Unknown
NuGet.PackageManagement.VisualStudio.dll!NuGet.PackageManagement.VisualStudio.DefaultTFSSourceControlManager.DefaultTFSSourceControlManager(NuGet.Configuration.ISettings settings, EnvDTE80.SourceControlBindings sourceControlBindings) Unknown
NuGet.PackageManagement.VisualStudio.dll!NuGet.PackageManagement.VisualStudio.VsSourceControlManagerProvider.GetSourceControlManager.AnonymousMethod__4_0() Unknown
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext(object stateMachine) Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run() Unknown
Microsoft.VisualStudio.Threading.dll!Microsoft.VisualStudio.Threading.JoinableTaskFactory.SingleExecuteProtector.TryExecute() Unknown
Microsoft.VisualStudio.Threading.dll!Microsoft.VisualStudio.Threading.JoinableTaskFactory.SingleExecuteProtector..cctor.AnonymousMethod__20_0(object state) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler = null) Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state) Unknown
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(object obj) Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext = {MS.Internal.CulturePreservingExecutionContext}, System.Threading.ContextCallback callback, object state) Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd = {System.IntPtr}, int msg = 49946, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr}, ref bool handled = false) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler = null) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd = {System.IntPtr}, int msg = 49946, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr}) Unknown
@tamirdresher this is because the API call to Path.GetFileName is throwing when it's getting " D:\tfs\Testvs17\.tt " The problem is the . in the path.
Do you know where is this path coming from?
@rohit21agrawal I saw the path but i have no idea where is it coming from. The root folder for the *.sln is D:tfsTestvs17 but i dont know where the .
and the rest is coming from.
I unbound the entire folder from TFS (VSTS) and now it works.
Do you have clue why working with a project that is bound to TFS can cause this error?
@tamirdresher I am investigating the issue - can you tell me if the solution packages folder is also bound to TFS?
UPDATE: I am unable to repro the issue in either case :/
Any chance you can create a repro TFS project and share it with me?
@CoolDadTx looked at your issues. It's actually a package issue with EntityFramework where they end up creating that file on uninstall. You can repro it by following the same steps, except that instead of migrating , uninstall the EntityFramework package and you will see the empty app.config appear.
Unfortunately, there is nothing we can do about it :( .
Hi,
I tried upgrading my VS 2017 project to PackageReference. I upgraded using the tool given here:https://marketplace.visualstudio.com/items?itemName=CloudNimble.NuGetPackageReferenceUpgrader
Once the upgrade was done, I deleted the packages folder from my solution and then Restored Nuget Packages. Seeing the following issues:
@techie55 that tool is not provided from NuGet team so it might not be following the right pattern to upgrade all your existing packages from packages.config to PackageRef.
Please use latest VS preview release from https://www.visualstudio.com/vs/preview/ and then try upgrading your individual projects to PackageRef and let us know if you see any issue there. Please find more details in this blogpost
When this tool is officially released, will it be possible to use the command line to invoke a migration, so it can be scripted? We have hundreds of solutions across many repos and doing this manually would be a pain.
Just checking - Did this ship in 15.7, or should I see it in the 15.8 preview (now that 15.7 has shipped)
(I ask as I can't see it in either of these)
It's shipped as part of 15.7. Please find more details from https://blog.nuget.org/20180409/migrate-packages-config-to-package-reference.html and if you still don't see the option then open an issue with repro steps.
@jainaashish Same question as @flcdrg . I do not see the option in my Visual Studio Community version
Attaching the images to verify.
The option is enabled only on certain projects and disabled for projects such as C++ and ASP.NET to name a few.
Also, make sure you open the NuGet package manager UI or console first before checking for the migration option
@rohit21agrawal We should probably update the documentation to add the following step:
Make sure you open the NuGet package manager UI or console first before checking for the migration option
After doing the above step, I can see the option Migrate packages.config to PackageReference
Any reason why this tool cannot be enabled for ASP.NET projects?
Just curious if anyone else has tried this on an existing project?
When I try it, it causes a complete removal of all Nuget packages.
Followed by an "invalid nuget configuration" error post migration.
Followed by a working Nuget Manager ui after restarting vstudio, with a [restore] button which looks like it works but restores nothing.
Followed by manually having to re-add all nuget packages, which results in a new packages.config file, starting me back at the beginning.
The migration wizard is clearly non functional and vstudio integration has some issues.
I was excited to hear about this new feature. But now, not so much. I'll come back when the kinks are worked out. good day to you.
Can you share a repro project with us please where this happens? This is clearly not supposed to happen and we are sorry you had to face this inconvenience. Having said that, we are very interested in solving this issue and making this experience better for you, so any details you can share with us will be greatly appreciated
No apologies necessary, I know you guys are working on things far more advanced than I can even comprehend. I'll see if I can get a reproduction repo built up and on github later today, and will post back. Might even find the issue that way, thank you :)
I am having similar issues as ensemblebd when I use the tool. Sometimes the restore failed, it suggest me to roll back. Sometimes it shows the migration succeed and .html/backup files are generated, but actually when I look at the modified .csproj file, no package reference is added or no
It doesn't happen to all my project, only some of them.
@memao can you share some of the projects with us? If there is any confidential information involved, we can set up a NDA and follow due process.
@techie55 the reason I suggested opening the PM UI/Console first is because I realized we ended up shipping a bug, for which I will file a tracking issue and fix as appropriate. In the meanwhile, we will work on documenting this workaround so people don't get blocked on this! Thanks for your feedback!
Hi,
I feel this feature is not very useful because it is not implemented for Web and WebAPI projects. Most of our projects are web based and I would have loved to see this feature available for Web projects as well
I'd like to reiterate @Falconne's question. Will there be the option to use this from the command line? We're keen to make this move, but doing this manually would be prohibitive.
@sclarke81 as of now there is no plan to have a command line option. Besides the right approach of migration is to uninstall the current package from packages.config
and reinstall with PackageReference
which is hard to achieve through a command line tool specially the uninstallation part.
@jainaashish Any update on the packagereference support being available for Web projects (ASP.NET full framework) ? We have an issue that is dependent on this support being available. (https://github.com/Microsoft/testfx/issues/241)
We're talking to AS.NET full framework team to be able to support PackageReference
for this but there are some core issues with existing ASP.NET specific packages to be able to work well with PackageReference
like Content
folders, install.ps1/ uninstall.ps
, XDT transform
, etc... which is why we have not been able to make much progress.
We're evaluating multiple options at this time, one such option is to at least allow people to be able to migrate their ASP.NET projects to PackageReference
and shows clear warnings with existing packages being used as part of that project which wont be compatible after migration so that consumers can take their own call (in some cases, it might just work like WebForms has less dependencies on content specific packages, or ASP.NET is also migrating to LibMan for content packages, etc...). But we're still evaluating and nothing is finalize yet. Will keep on posting as soon as there is any decision on it.
cc @rrelyea @DoRonMotter
@jainaashish Will you consider updating Microsoft.CodeAnalysis.Analyzers and Microsoft.CodeDom.Providers.DotNetCompilerPlatform to be compatible with PackageReference? Most of the popular libraries provide .net standard versions, but those dlls are from Microsoft, and they are the one providing warnings in most of our asp.net project, when we manually convert them to PackageReference.
You can ignore warnings for Microsoft.CodeAnalysis.Analyzers
package since it works fine for both PackageReference
. We can improve our tool to ignore warnings for analyzers
packages... tracking issue# https://github.com/NuGet/Home/issues/7208
For Microsoft.CodeDom.Providers.DotNetCompilerPlatform
We'll talk to the corresponding owners to update their package to be compatible with PackageReference
Hasn't been any activity on this for 1.5 months - I am wondering if we are any closer to supporting shifting ASP.NET projects to PackageReference? this has been a big blocker for our team to shift to .NET core / standard.
Migrating ASP.NET projects to PackageRefs is possible. Only issue is that
frontend
nuget packages won't install, to overcome this problem you could
migrate to LibMan that is included in the latest VS release
On Thu, Oct 4, 2018 at 1:07 PM nzandy notifications@github.com wrote:
Hasn't been any activity on this for 1.5 months - I am wondering if we are
any closer to supporting shifting ASP.NET projects to PackageReference?
this has been a big blocker for our team to shift to .NET core / standard.ā
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/NuGet/Home/issues/5877#issuecomment-426978044, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ACg1kpVmDZOT7p0zbBW0ucnytqxO0D-Yks5uhevbgaJpZM4PT0aq
.
--
Met vriendelijke groet,
Jarno Nijboer
[email protected]
@JarnoNijboer NuGet still needs to add support for adding files to the project, via a regular NuGet package that is not front-end... This has been the main blocker for my team.
@JarnoNijboer that is the problem our team faces.
Shifting to use LibMan doesn't seem like a small task for us.
If you're "still" using NuGet for client side packages then LibMan would be a first step but honestly everybody uses NPM for that now. If you're going to take the hit to switch from client packages to LibMan then I'd just forgo that and go straight to NPM. VS is fully integrated with it as is all build systems.
But as @caioproiete mentions, there are other (non-front end) packages that you still need NuGet for. Pretty much any package that wants to insert new code into your project or modify your configs don't work properly with package reference. Some functionality can be restored if the package is updated to use the newer content file model but that assumes the package is being maintained.
Appreciate the feedback. I haven't been too involved in the front-end side of our projects. I have heard it mentioned about ideally moving to npm but hasn't seemed to gain traction so far.
In regards to the other shortcomings of the PackageReference format - why is this the case? Are the issues likely to be "fixed" in the future? or do these issues not exist for new .NET core projects? is it just a pain for those developers attempting to migrate .NET framework projects?
@nzandy, this doesn't really have anything to do with .NET Core but changes to NuGet itself. The NuGet team, for better or worse, has decided that how packages worked in the past won't do that now. So we are still dealing with the ramifications of these changes. The specific changes that impact this issue (as I understand them) is that packages installed via PackageReference don't go into the solution anymore. They are stored in a per-user cache to optimize the downloads.
Additionally packages that rely on other packages aren't "installed" into projects anymore. NuGet does a dependency graph traversal to pull in dependent packages at restore time. So there is no install step for packages hence content files and install scripts don't run.
This is by design so it won't be "fixed" nor is it just for NF apps. Everybody using PR is impacted and this is how it will work going forward. There are still gaps in the PR implementation and the NuGet team seems really slow on getting the feature sets more level so at this time I don't know what is going on.
We're talking to AS.NET full framework team to be able to support
PackageReference
for this but there are some core issues with existing ASP.NET specific packages to be able to work well withPackageReference
likeContent
folders,install.ps1/ uninstall.ps
,XDT transform
, etc... which is why we have not been able to make much progress.We're evaluating multiple options at this time, one such option is to at least allow people to be able to migrate their ASP.NET projects to
PackageReference
and shows clear warnings with existing packages being used as part of that project which wont be compatible after migration so that consumers can take their own call (in some cases, it might just work like WebForms has less dependencies on content specific packages, or ASP.NET is also migrating to LibMan for content packages, etc...). But we're still evaluating and nothing is finalize yet. Will keep on posting as soon as there is any decision on it.cc @rrelyea @DoRonMotter
@jainaashish @rrelyea @DoRonMotter Any updates here ?
Work faster.
There is a VSIX extension that supposedly allows migration of ASP.net web projects. However it breaks when trying to migrate VB.Net projects. We are trying to migrate away from VB.Net completely but it takes time. We really would like to change from package.config to the package reference format. Is there some way to do this manually for now?
for the sole purpose of enabling and completing the migration, you can remove the following guids from your project file:
{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}
{349C5851-65DF-11DA-9384-00065B846F21}
{E24C65DC-7377-472B-9ABA-BC803B73C61A}
The presence of the above GUIDs causes NuGet to not show the Migrate dialog on right clicking the project.
NOTE: Might cause certain other functionality to stop working. Restore them after migration is complete.
THanks, that allowed me to do the migrations.
Does the package manager work for that project, though, after this hack? Like, restore and update?
Seems to be.
When is Microsoft going to add support for PackageReference for ASP.NET Web Forms packages??? I suppose never, since they are throwing Web Forms under the bus. Thanks a lot Microsoft.
I have successfully used the work-around described above and so far I haven't seen any issue. Makes me wonder why isn't it working by design for the web projects? What issue do I have with them that I am not yet seeing?
If you switch an existing project from package.config (PC) to package reference (PR) then you'll have no issues. In fact any project that supports PC supports PR as it is a built time featue. Your builds will work just fine.
The issue with PR is that it doesn't support all the scenarios that PC installs did and this is where things go wrong. Specifically PR doesn't support running install/uninstall scripts when a package is added/removed. Therefore any package that makes changes to a project during install (such as modifying the config file, adding project files, etc) don't work in PR. If you install a package using PR that has an install script then it adds the package but doesn't do anything else.
This is why ASP.NET apps aren't formally supported yet. For many ASP.NET-specific packages they need to update the system.web
or system.webserver
sections of the config file and/or add files to the project that can then be compiled into code. That simply doesn't work in PR. Since it can be very hard to know what a package does without opening it up and looking at the install script the current recommendation has been to stick with PC. In some cases PR has been updated to support some features but because of transient package resolution this doesn't work unless you explicitly include a package. That defeats one of the benefits of PR.
So yes you can use PR with any project that supports PC but you have to be aware of any install scripts that won't run and manually make the changes yourself. If you have the expertise to do that then go for it. However be aware that future updates to packages may change things so each time you update a package you need to review the scripts. This adds an extra layer of work for little gain in most cases. Hence most people stick with PC. Note that you can mix this in the solution. For example at my company we use PR for everything except ASP.NET and WCF projects. These projects stick with PC while the rest of the code in the solution use PR.
If it were possible to generate web.config
at build-time with MSBuild targets hooks for incrementally building it, which people would only do if MS lead the effort by changing the templates to do so, it would be possible for ASP.NET-style projects to switch to PR in a clean way.
@binki, you can already do that. MSBuild tasks can generate/update config files at build time. That is how the AutoGenerateBindingRedirects property works. Packages can integrate into the build process with custom .props and .targets files. This is how the more complex packages work. As such a package can integrate into the build at any point in the process just like anything else.
What cannot be done via MSBuild is anything that is needed at design time such as generating user-editable files. Adding files to a project at build time is easily handled in MSBuild and, once again, already done by the SDK format when generating assembly info files. But design time (e.g. before the build) changes cannot be done.
@CoolDadTx I understand that. What Iām saying is that web.config
is considered a āuser-editable fileā. It doesnāt have to be if the ASP.NET tooling were updated to make it a generated file. Of course, that would be very difficult to do and would break a lot of things which assume it is user-editable.
@binki, web.config
has to be editable because devs do edit it. It is no different than an app.config
in every other project type. You said making this auto-generate would solve the PR issue for ASP.NET. I fail to see how this feature (which already works) solves the problem with migrating ASP.NET apps to PR. Config files are easy to change at build time. This isn't what makes updating ASP.NET apps hard. It's the other stuff like updating bundling rules when adding content files or modifying the config file when there are user-settable options inside it (e.g. identity providers).
Can't merge conflicts be detected and the dev prompted to solve them? Worst case, can't the user-modified sections which the PR changes be commented out (rather than wiped out), so the dev can see them after adding a package?
@hyankov Who is your comment directed to? I don't understand what you mean by a merge conflict as that would only apply to a PR. Since packages cannot modify configs at install time anymore (because there is no install) then the only file changed when adding a package is the project file (to add the package reference element).
Is there a right-click menu to convert a ASP.NET Web Forms application project to use PackageReference yet? If not, the problem is not fixed. Which isn't a surprise because it is clear that Microsoft could give a flying you know what about Web Forms. They already threw it under the bus with .NET Core. Instead, they want you to port your code to unreleased vaporware.
@CoolDadTx
@binki,
web.config
has to be editable because devs do edit it. It is no different than anapp.config
in every other project type. You said making this auto-generate would solve the PR issue for ASP.NET. I fail to see how this feature (which already works) solves the problem with migrating ASP.NET apps to PR. Config files are easy to change at build time. This isn't what makes updating ASP.NET apps hard. It's the other stuff like updating bundling rules when adding content files or modifying the config file when there are user-settable options inside it (e.g. identity providers).
web.config
doesnāt have to be editable. It could be built from other files, some which are user-edited and others which are transformations applied incrementally by targets from <PackageReference/>
. What youāre saying is something like āweb.config
has to be editable because it currently is editableā. What Iām saying is that the <PackageReference/>
approach would be a lot easier if Visual Studio were willing/able to run targets to generate web.config
, default to web.config
being in .gitignore
, have a user-friendly way to store the edits that you would need to make to web.config
in different files which automatically get applied to the web.config
as it is generated, and public well-specified MSBuild targets that would collect information for generating web.config
and run when it needs to be generated (such as after the user edits the user-editable files).
The same approaches can be extended to bundling rules. IMO, the system is broken if a file is both autogenerated and requires post-generation user edits before it works for them.
Making web.config
built would make a lot of projectsā git repos a ton cleaner because they would be able to have less generated code in them. This gets us closer to the ideal of 0 boilerplate. It would allow projectsā git repos to contain exactly the code that is specific to that project and omit things which are needed for every project like FSharp assembly binding redirects (for non-ASP.NET projects, those are already autogenerated at build-time because app.config
is transformed while it is being copied to bin
. In ASP.NET projects, the web.config
in the root of the repository has to be post-transform because that is where IISExpress looks when serving the projectāwhich is one of the few reasons why VS still must implement the functionality where it can edit app.config
/web.config
for you if you right-click the error message about missing binding redirects).
@binki, while I agree that separating web.config
into separate pieces (which you can already do by the way) would make it easier to autogenerate stuff. This doesn't really have anything to do with PR in ASP.NET projects. Your thoughts sound more like a feature request and therefore should probably be posted in the ASP.NET team. Breaking up web.config
would not solve the PR issue with ASP.NET projects. It would simply lessen the things that need to be done to get it to work.
@CoolDadTx
This doesn't really have anything to do with PR in ASP.NET projects.
Iām convinced it is a big part of it. The installation/uninstallation scripts that packages.config
run primarily do things like edit app.config
/web.config
. Bundled assets are already solved. However, there is no way for a <PackageReference/>
NuGet to edit app.config
upon installationāwhich is a good thing. It enforces less boilerplate. .csproj
files no longer generate a bunch of churn when updating or adding/removing packages to a project.
separating
web.config
into separate pieces (which you can already do by the way)
Where are the docs on this? I donāt expect NuGet package authors to write targets to work with one personās way of autogenerating configuration files because there is not yet a right way to do so. Microsoft needs to make a guide on how to write a NuGet which can be installed into an ASP.NET project as <PackageReference/>
and still work without requiring the user to read and manually do the steps outlined in install.ps1
.
@binki, I'm afraid we'll have to disagree on this. Separating out the config file introduces way more problems then it solves (especially at runtime where multiple files are now needed) just to get PR to work and there are still cases where PR won't work with a package. Since ASP.NET is deprecated in lieu of ASP.NET Core (which focuses on programmatic configuration and JSON instead of web.config
) I doubt MS would take the hit to implement such a feature vs just forcing everyone down the ASP.NET Core route.
Where are the docs on this?
configSource is what handles this. Some larger apps use it to separate their configurations out. Personally I find it harder to work with but I can see the draw for really large apps.
Where are the docs on this?
configSource is what handles this. Some larger apps use it to separate their configurations out. Personally I find it harder to work with but I can see the draw for really large apps.
I know what configSource
is and have looked at it. But what you linked is not a protocol for writing a <PackageReference/>
-compatible NuGet package intended for consumption by ASP.NET.
Since ASP.NET is deprecated in lieu of ASP.NET Core
OK, so I am reading that is: MS does not intend to fix this issue. Thanks for the update!
OK, so I am reading that is: MS does not intend to fix this issue. Thanks for the update!
I don't work for MS so I cannot answer the official word on the matter but if you read all the information coming out, including .NET 5 then the writing is on the wall.
Most helpful comment
If you switch an existing project from package.config (PC) to package reference (PR) then you'll have no issues. In fact any project that supports PC supports PR as it is a built time featue. Your builds will work just fine.
The issue with PR is that it doesn't support all the scenarios that PC installs did and this is where things go wrong. Specifically PR doesn't support running install/uninstall scripts when a package is added/removed. Therefore any package that makes changes to a project during install (such as modifying the config file, adding project files, etc) don't work in PR. If you install a package using PR that has an install script then it adds the package but doesn't do anything else.
This is why ASP.NET apps aren't formally supported yet. For many ASP.NET-specific packages they need to update the
system.web
orsystem.webserver
sections of the config file and/or add files to the project that can then be compiled into code. That simply doesn't work in PR. Since it can be very hard to know what a package does without opening it up and looking at the install script the current recommendation has been to stick with PC. In some cases PR has been updated to support some features but because of transient package resolution this doesn't work unless you explicitly include a package. That defeats one of the benefits of PR.So yes you can use PR with any project that supports PC but you have to be aware of any install scripts that won't run and manually make the changes yourself. If you have the expertise to do that then go for it. However be aware that future updates to packages may change things so each time you update a package you need to review the scripts. This adds an extra layer of work for little gain in most cases. Hence most people stick with PC. Note that you can mix this in the solution. For example at my company we use PR for everything except ASP.NET and WCF projects. These projects stick with PC while the rest of the code in the solution use PR.