How to deploy dacpac file from a nuget package in c# - c#

I have a nuget package containing my SQL database project. How can I reference the dacpac file in the package in order to deploy it to my azure sql server? I would like to do this from my ASP.net core application.

I needed to do this too, so here is what worked for me:
If your application uses the new SDK format, you can reference content files in a referenced nuget package in your project. You need to add the <GeneratePathProperty> node with a value of true in the package reference:
<ItemGroup>
<PackageReference Include="My.Package" Version="1.0.1">
<GeneratePathProperty>true</GeneratePathProperty>
</PackageReference>
</ItemGroup>
Then you can include the file you want to reference using a content link. The VS variable name is by convention starting with the prefix "Pkg" and replacing periods with underscores. You can also optionally include a <Link> node which provides a "notional" path for the included file when viewing it in your project. Example below:
<ItemGroup>
<Content Include="$(PkgMy_Package)\contentFiles\any\net48\SomeDb.dacpac">
<Link>dacpac\SomeDb.dacpac</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Pack>true</Pack>
</Content>
</ItemGroup>
The content file will be copied to the build output folder during build just like any other content file.
This is supported from VS 2017 15.9. Credit to Georg Dangl from his blog post: https://blog.dangl.me/archive/accessing-nuget-package-paths-in-your-net-sdk-based-csproj-files/

Related

Why is VS2019 still copying embedded resources to the output folder?

When i try to embed resources in a .NET Core Webservice project via EmbeddedResource in the .csproj file, these resources are also copied into the output folder, although i choose the option to NOT copy in the build action dropdown-menu.
The part where the resource is embedded looks like this:
<ItemGroup>
<EmbeddedResource Include="Resources\logging.json" />
</ItemGroup>
In another .NET Core project, which is a library, the resource gets embedded and won't be copied to the output directory.
There, the snippet looks like this:
<ItemGroup>
<EmbeddedResource Include="LicenseText\*.txt" />
</ItemGroup>
Is there an explanation to this behaviour?
I can reproduce your issue on my side. I checked the official document about EmbeddedResource item, and the metadata introduced like this
CopyToOutputDirectory Optional string. Determines whether to copy the file to the output directory. Values are: 1. Never. 2. Always. 3. PreserveNewest.
I tested by adding related metadata into .csproj file manually, but the issue remained.
<ItemGroup>
<EmbeddedResource Include="Resources\logging.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
I think this should be a potential issue and I have reported it to Microsoft Developer Community, hope VS product team can fix it and share the insights. Here is the link: Embedded Resources still copy to output directory even set CopyToOutputDirectory to Never.

Have a NuGet package output a file

I have a Visual Studio project that I have made into a NuGet package. The project has a file in it (called SwaggerIndex.html). I have set that file to have the "Copy to Output Directory" property to "Copy if newer". (I need this file to copy to the build folder on build.)
In that solution it works just fine. (I created another project to test it, and when it references my project that has the SwaggerIndex.html, it outputs it to the build folder just fine.)
However, when I package it into a NuGet and pull it into another solution/project, the SwaggerIndex.html file is not output on build.
I am making my NuGet package by going to the project's "Package" properties tab and selecting "Generate NuGet package on build". All projects involved are running .Net Core 3.1.
How can I get my NuGet Package to create my SwaggerIndex.html file on build (like it does when it is just a normal project)?
Please try these:
I have two solutions for you to solve the issue.
Solution 1
If you just want to install this nuget package only in new sdk projects(Net Core and Net Standard projects), you could use this
1) add these node in your xxx.csproj file:
<ItemGroup>
<None Include="xxx\SwaggerIndex.html(the path of SwaggerIndex.html file in your project)" Pack="true" PackagePath="contentFiles\any\any">
<PackageCopyToOutput>true</PackageCopyToOutput>
</None>
</ItemGroup>
2) then repack your nuget project, and before you install the new version, you should first clean nuget caches first or just delete all cache files under C:\Users\xxx(current user)\.nuget\packages
Solution 2
If you want this nuget package to copy SwaggerIndex.html file in both Net Framework and Net Core projects, you should use this:
1) add a file called <package_id>.props file in your nuget project. You should note that if your nuget package named as SwaggerIndex.1.0.0.nupkg, you should name the file as SwaggerIndex.props file so that it will work.
In my side, I put it into a folder called build.
2) then add these content in SwaggerIndex.props file,
<Project>
<Target Name="CopyToOutputFolder" BeforeTargets="Build">
<ItemGroup>
<File Include="$(MSBuildThisFileDirectory)..\File\*.*"></File>
</ItemGroup>
<Copy SourceFiles="#(File)" DestinationFolder="$(TargetDir)"></Copy>
</Target>
</Project>
3) add these in xxx.csproj file of your nuget project.
<ItemGroup>
<None Include="SwaggerIndex.html" Pack="true" PackagePath="File"></None>
<None Include="build\SwaggerIndex.props" Pack="true" PackagePath="build"></None>
</ItemGroup>
4) then repack your nuget package, before installing this new version of the nuget package, you should first clean all nuget caches first.
When you finishing installing the new version of the nuget package, click Build and the file will be copied into the main project.
Besides, there is also a similar issue about this.

How do I include a non-dll file from build output (dacpac) in a dotnet pack nuget package?

I currently have a .NET Standard 2.0 library that is a repository against a sql database. I also have a .sqlproj project in the same solution for that particular database. The repository library gets built, packed, and pushed to our nuget repository from our build server (Azure DevOps) using the dotnet pack command on 2.2 cli. I would like to include the dacpac from the database project as part of the repository nuget package so that releases from consumers of that package can deploy the dacpac changes. I plan on making sure that the version being overwritten is later than the package version on deployment.
I am able to add the dacpac file to the build output of the repository project by using a before build target
<Target Name="mydb" AfterTargets="Build">
<Exec Command="XCOPY /Y /R ..\db\bin\$(ConfigurationName)\mydb.dacpac $(TargetDir)" />
</Target>
My current issue is that although the file copies, it is not included in the resulting nuget file from
dotnet pack repository.csproj
I found the answer in the depths of MS documentation:
In addition to the target, I needed to add a Content to include the file that I just copied.
<ItemGroup>
<Content Include="$(TargetDir)\mydb.dacpac" >
<Pack>true</Pack>
<PackagePath>\dacpacs\</PackagePath>
</Content>
</ItemGroup>
https://learn.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package-using-visual-studio?tabs=netcore-cli

Can dotnet pack create a nuget package without adding content files from other nuget packages?

I'm trying to setup a library nuget package for .net core with the dotnet pack command, however, instead of just having a dll included in the nuget package, a content file from another references nuget is added (which makes the nuget file size 9.6MB instead of 59KB).
Is there a way to avoid getting files and content from other nuget packages in a nuget library project?
to reproduce:
Create a .net core library
Add Hl7.Fhir.Specification.STU3 nuget reference
run dotnet pack
The nuspec file in the newly created nuget package, will reveal that the specification.zip file is regarded as content that must be added.
I've tried testing with a custom nuspec file which is basicly a copy from the dotnet output, but without the content reference. The problem I see, is that the nuspec file contains a lot of references which must be maintained somehow.
Peter Wurzinger's suggestion worked for me. It's a shame he posted as a comment, rather than an answer, since he deserves the rep points. Anyway, this is my csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Hl7.Fhir.Specification.STU3" Version="0.96.0" ExcludeAssets="contentFiles" />
</ItemGroup>
</Project>
when I pack, the bin\Debug\test.1.0.0.nuspec file does not contain the specification.zip file elements that exists when I don't use ExcludeAssets.

How to determine behavior of binaries in NuGet package

There is this big solution I'm working on, where I turned a lot of the projects into NuGet packages. The packages were created via a .nuproj file in a separate solution in VS.
Everything works fine, except for the following:
At bootstrap I load some catalogs for MEF to be able to import them, which worked perfectly when I worked with the original projects, but now the needed DLLs (which come from the a package) don't make it to the bin\Debug\Modules folder.
Is there a way to make NuGet copy its content to the Modules folder? (and not to the root path)
I tried using the different kinds of sub-folders inside the package with no success.
I found that the best solution for this matter is the following:
Take the files that need to be loaded and put them on the content folder. This can be done simply:
<ItemGroup>
<Content Include=" {here go the needed files} " />
</ItemGroup>
The content folder just holds the files, but it does not copy them to the output folder on the client project. In order to copy them to the desired output, a .targets file can be used, just like the following:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyToOutput" AfterTargets="Build">
<ItemGroup>
<FilesToCopy Include="$(MSBuildThisFileDirectory)..\content\**\*.*"/>
</ItemGroup>
<Copy
SourceFiles="#(FilesToCopy)"
DestinationFiles="#(FilesToCopy->'$(OutDir)/%(RecursiveDir)%(FileName)%(Extension)')"/>
</Target>
</Project>
Keep in mind that the targets file name and the ID of the NuGet have to be equal for the targets file to be added to the project.
You should be able to use a target of content/Modules. Anything in the content directory is copied in to the bin directory on build.
If you were trying to use the special "convention based" folders, like lib/net45, those are directories that cause Visual Studio to automatically create an assembly reference when the package is installed. You shouldn't use those for regular content files.
See the documentation for more details.

Categories