ASP.NET Core- wrong processPath in generated web.config - asp.net-core

I have rather strange problem.
One of the applications we are working on stopped working after publish to Azure Web App. Everything works ok locally. After long investigation, the culprit is that the web.config generated by the build (in VSTFS) has this:
<aspNetCore processPath=".\SomeServiceName.Api " stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
While the correct one is:
<aspNetCore processPath=".\SomeServiceName.Api.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
Note the missing .exe.
The build output of the project is set to Console Application. It's ASP.NET Core app, running on full framwork. The build is run using Visual Studio Build task in VSTS, with following MSBuildArguments:
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)"
If I run the build on my dev machine, using MSBuild cli, with the same command line arguments, I get this:
<aspNetCore processPath="dotnet" arguments=".\SomeServiceName.Api.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
The project is using <Project Sdk="Microsoft.NET.Sdk.Web">.
I'm guessing I could just add web.config to the project (it's not there at all now) and have it in source control the way I want, that should fix my immidiate problem of broken deployments. But I would like to know:
The web.config genrated by build on VSTS is obviously wrong. Is that a bug in Microsoft.NET.SDK.Web thing?
I don't have access to the actuall build server. I'm guessing that the only reasonable explanation is that someone updated .net core SDK, which is why the behaviour changed. Does this make sense? Does the msbuild targets come from .NET Core SDK, or is that part of visual studio?
I'm getting different web.config on my machine. Why is that?
Update:
For anyone who stumbles here, here's the link for issue on github:
https://github.com/aspnet/websdk/issues/408
Looks like this is now fixed and will be part of some release some day (No idea what's the release cycle though).

I had exactly the same problem, and I solved it last week.
We had 2 ASP.Net Core projects, one showing the issue, the other didn't have the issue. So we compared the 2 .csproj files.
Turns out that in our case, all we needed to do was delete the
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
properties from the .csproj; once that was done, MSBuild correctly created the web.config, including the .exe at the end of the processPath.

I had exactly the same problem, and I solved it last week. We had 2 ASP.Net Core projects, one showing the issue, the other didn't have the issue.
Firstly check C:\Program Files\dotnet path, if the 'sdk' folder is not available then you need to install the ASP.NET Core SDK. If you install this package then the problem is resolved and the app is running with:
<aspNetCore processPath="dotnet" arguments=".\yourapp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout"/>

A few options for getting the .exe in there. Each of these methods worked for me:
Switch the build configuration from Debug (the default) to Release:
dotnet publish -c Release or msbuild argument /p:Configuration=Release
Create a web.config the way you want it in the root of your project and then tell the SDK not to touch it by adding the following to your project file:
<PropertyGroup>
<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>
Specify your target runtime as one of the win-* runtimes listed at https://learn.microsoft.com/en-us/dotnet/core/rid-catalog. Here's the code that appears to be adding the exe extension:
https://github.com/aspnet/websdk/blob/6b898ad0a39329ab5f0db281a9c1712e4303ed61/src/Publish/Microsoft.NET.Sdk.Publish.Targets/netstandard1.0/TransformTargets/Microsoft.NET.Sdk.Publish.TransformFiles.targets#L44

Related

Why is .Net Core 2.2 now publishing a ton of other dlls

I just upgraded my .net core 2.0 project to 2.2. To my knowledge, I didn't change any other settings, but now when I publish to my file system, it publishes a ton of folders and dlls that it didn't before.
Do I need to publish them? If not, can I suppress their output?
Here is my publish profile settings:
Here is what the output directory looked like before the upgrade:
Now, here is just a snippet of what the output directory looks like:
Introduction: This issue seems to result from .net core 2.0.
From the picture you shared above. I know you choose Framework-Dependent Mode.
In this mode, generated files should be like what you have in picture1. And if your choose self-contained mode, generated files should be like what you have in picture2.
But in .net core2.0, there seems to be some different. When we publishing projects in .net core2.0, or just upgraded from 2.0 like yours. We must set self-contained property to false explicitly so that the Framework-Dependent mode can work normally.
Do I need to publish them?
No, you don’t need to publish generated files from self-contained mode as you choose framework-dependent mode.
If not, can I suppress their output?
Here is one workaround:
Looks like you use VS IDE to publish it, when publishing make sure choose 'create profile'. So we will have a PublishProfile, we can find it below Properties in Solution Window. Open the FolderProfile.pubxml and add the <PublishWithAspNetCoreTargetManifest>true</PublishWithAspNetCoreTargetManifest> in the PropertyGroup. Also, we can set the <DeleteExistingFiles>false</DeleteExistingFiles> to true.
After that, publish the project again the issue can be resolved.
The final format of PublishProfiles looks like below:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
...
<publishUrl>bin\Release\netcoreapp2.2\publish\</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
<PublishWithAspNetCoreTargetManifest>true</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>
</Project>
In addition: You can find more info from this issue. Thanks to natemcmaster. His advice do work at my side.

How to specify a custom parameters.xml when building a Web Deploy package for ASP.NET Core?

Overview
I am building a deployable web package that can be imported into IIS that automatically prompts for settings needed by my ASP.NET Core application. I already created a package that will deploy just fine, except after deploying, I need to manually find/edit my appsettings.json file.
I know this package can include a parameters.xml file that will automatically prompt and fill in my appsettings.json when importing an app into IIS. I have already made a parameters.xml file, and manually added it to my package after building it; it worked as expected. I'd just like to have msbuild automatically add the parameters.xml file to the package for me.
A separate project of mine (ASP.NET MVC 4) already does this. For that, I simply needed to put my parameters.xml in the same folder as my .csproj. I tried doing the same here, but had no luck.
Repro Steps
I created an ASP.NET Core Web Application
Using .NET Framework on ASP.NET Core 1.1
I then went to publish my website
Selected 'Folder' (just to get a template)
I then edited the profile and changed the WebPublishMethod to Package and added the three lines below it.
<DesktopBuildPackageLocation>bin\$(Configuration)\$(MSBuildProjectName).zip</DesktopBuildPackageLocation>
<PackageAsSingleFile>true</PackageAsSingleFile>
<DeployIisAppPath>External</DeployIisAppPath>
I then published one more time. Now I get a WebDeploy package that I can deploy to IIS.
Great! but...
I'd like to customize the parameters.xml.
For previous projects, I was able to add a parameters.xml file to my project root, and VS/msbuild would automatically add it to my published package. This currently works for a different project using ASP.NET MVC 4.
So, I tried the same thing for this project. First I added a settings.json with a very simple setting:
{
"SettingName": ""
}
Then I added a parameters.xml file that I know works to my project root. (If I manually replace the parameters.xml file in Sample.zip package, it correctly prompts and replaces my setting when deploying)
<parameters>
<parameter name="IIS Web Application Name" value="External" tags="IisApp">
<parameterEntry kind="ProviderPath" scope="IisApp" match="^c:\\users\\joshs\\documents\\visual\ studio\ 2017\\Projects\\Sample\\Sample\\obj\\Release\\net461\\win7-x86\\PubTmp\\Out\\$" />
</parameter>
<parameter name="Setting Name" description="Enter a custom app setting" defaultValue="Default Setting Value">
<parameterEntry kind="TextFile" scope="obj\\Debug\\net461\\win7-x86\\PubTmp\\Out\\appsettings\.json$" match="(?<=\"SettingName\"\s*:\s*\")[^\"]*" />
</parameter>
</parameters>
Again, I right click and Publish once more. This time with the parameters.xml file.
I expect the Sample.zip to contain the parameters.xml that I added to my project root, but it does not. It is the exact same as from my original publish.
Question
During the build process when creating a web deploy package, how do you include custom settings in the parameters.xml?
I have already tried this...
I already looked at https://stackoverflow.com/a/46338042/2494785, but with no luck, though my command differed slightly from the original poster.
PS C:\Users\joshs\Documents\Visual Studio 2017\Projects\Sample> & 'C:\Program Files (x86)\Microsoft Visual Studio\2017\E
nterprise\MSBuild\15.0\Bin\MSBuild.exe' .\Sample.sln /t:Sample /p:DeployOnBuild=true /p:PublishProfile=FolderProfile /p:
ProjectParametersXMLFile="C:\Temp\parameters.xml"
I was able to solve this from peteawood's comment from an issue posted on GitHub.
https://github.com/aspnet/websdk/issues/201#issuecomment-349990389
In ASP.NET Core 2.0+ you can add the following to your .csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
.
.
<Target Name="AddMoreParameters" AfterTargets="_CreateParameterFiles">
<Copy SourceFiles="Parameters.xml" DestinationFiles="$(_MSDeployParametersFilePath)" />
</Target>
</Project>
SourceFiles should point to the location of your parameters.xml file from the perspective of the .csproj file. My parameters.xml is found in the same directory as my project file.
I believe I can just pass parameters via cmd-line as properties for msbuild.
It's not fully what you asked for I understand.
For example, in the following command I'm passing DeployIisAppPath property:
dotnet publish /p:WebPublishMethod=Package /p:DeployIisAppPath=mysite/myapp /p:PublishProfile=rnddev03-core-dev
and in the output folder we'll get xxx.SetParameters.xml file with:
<parameters>
<setParameter name="IIS Web Application Name" value="mysite/myapp" />
</parameters>

.NET Core RuntimeIdentifier vs TargetFramework

Can someone explain the purpose of this two in csproj file (VS2017):
<TargetFramework>netstandard1.6</TargetFramework>
<RuntimeIdentifier>win7</RuntimeIdentifier>
I just migrated from VS2015 and now can't publish my web api because it looks I should use only one target framework. In addition I can't specify multiple RIDs.
All these changed things make me frustrated. Nothing works from scratch, should overcome something over and over.
I just want developing my web-api on windows, run xUnit tests here and then deploy web-api to run on linux (ubuntu) server.
What I should put in both parameters in csproj ?
Links with good explanation is highly appreciated.
Update1
I have web api with referenced .net core libraries. Everything where migrated from VS2015. Now in root project I have
<TargetFrameworks>netcoreapp1.1;net461</TargetFrameworks>. When I publish via VS2017 I got error:
C:\Program
Files\dotnet\sdk\1.0.3\Sdks\Microsoft.NET.Sdk\buildCrossTargeting\Microsoft.NET.Sdk.targets(31,5):
error : The 'Publish' target is not supported without specifying a
target framework. The current project targets multiple frameworks,
please specify the framework for the published application.
But I have specified target framework in publish as netcoreapp1.1.
OK. Then I updated my csproj with <PropertyGroup Condition="$(TargetFramework)'=='netcoreapp1.1'">
<RuntimeIdentifier>ubuntu.16.10-x64</RuntimeIdentifier>
</PropertyGroup> as suggested below.
But now I even can't build app, get error:
5>C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.targets(92,5):
error : Assets file '\obj\project.assets.json' doesn't
have a target for '.NETCoreApp,Version=v1.1/ubuntu.16.10-x64'. Ensure
you have restored this project for TargetFramework='netcoreapp1.1' and
RuntimeIdentifier='ubuntu.16.10-x64'.
I just want develop with VS2017 at windows 8.1/windows7 and deploy to ubuntu 16.10.
What I'm doing wrong ?
Update2
I have 8 projects in solution. 3 of them are xUnit tests. Thus we have 5 projects. 4 of these 5 are class libraries and 1 is my web-app.
All 4 class libraries have this:
<TargetFrameworks>netstandard1.6;net461</TargetFrameworks>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
My web app:
<TargetFrameworks>netcoreapp1.1;net461</TargetFrameworks>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
How to publish my web-app ?
The <TargetFramework> (or <TargetFrameworks> when you want have multiple targets, such as net451, one or multiple netstandard1.x etc). Per <TargetFramework> / <TargetFrameworks> entry one set of assemblies will be created and located inside bin\Debug\<targetframeworkid>).
This is useful, when you want to use a different library in .NET Core (because the library you used only works with full .NET Framework such as 4.5.1) or remove this feature from i.e. .NET Core because it's unsupported.
It is used for both, building and NuGet restore. i.e. you can't use a net451 only library in a .NET Core project (netstandard 1.1 for example - but you can use netstandard1.1 in a net451 project).
<RuntimeIdentifier> / <RuntimeIdentifiers> on the other side is used for NuGet mainly. It tells NuGet which packages you need. For example if you want to target Linux, Mac and Windows, certain assemblies require native libraries (such as encryption. On windows CryptoAPI will be used, but on Linux and Mac you need OpenSSL). This includes non-managed dlls and *.so (Linux) files.
i.e. <RuntimeIdentifiers>win7-x64;win7-x86;ubuntu.16.10-x64</RuntimeIdentifiers> will make nuget restore packages for win7 (both x64 and x86) versions and x64 only for ubuntu. This is required, because when you work on windows you need to download these native libraries too so you deploy/package them with dotnet publish.
Here's a little catch though: When you have a full .NET Framework reference in <TargetFramework> or <TargetFrameworks>, then you must specify a single <RuntimeIdentifier> (singular, not plural <RuntimeIdentifiers>), otherwise you will get an error.
For example:
<PropertyGroup>
<TargetFrameworks>netstandard1.0;net451</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win7-x86;ubuntu.16.10-x64</RuntimeIdentifiers>
</PropertyGroup>
<!-- This entry will only be used for the .NET Framework 4.5.1 output -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net451'">
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
</PropertyGroup>
RID is short for Runtime IDentifier. RIDs are used to identify target
operating systems where an application or asset (that is, assembly)
will run. They look like this: "ubuntu.14.04-x64", "win7-x64",
"osx.10.11-x64". For the packages with native dependencies, it will
designate on which platforms the package can be restored.
More in docs
First change to proper RID from win7 to win7-x64 or win7-x86. Next add other RID like ubuntu. For example:
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
<RuntimeIdentifier>win7-x64;ubuntu.16.10-x64</RuntimeIdentifier>
</PropertyGroup>
Target framework looking good. For more read docs

MSBuild - how to force "AfterBuild" target when I do deployment?

I have the following setup: ASP.Net MVC .Net 4.0 solution with 5 projects in it, and several solution configurations (Site1-Stage, Site1-Live, Site2-Stage, etc). The reason for this is simple - we deploy same codebase to multiple servers with different config settings.
To manage these configurations, I use the approach described by Troy Hunt in his You're deploying it wrong! TeamCity, Subversion & Web Deploy part 1: Config transforms article. In 2 words - I do NOT have web.config in my SVN repo, instead I have Web.Base.Config, Web.Site1-Stage.Config, etc and XmlTransformation task in project AfterBuild target. During the build, the required web.config is generated based on selected configuration:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild">
<TransformXml Source="Web.Base.config" Transform="Web.$(Configuration).config" Destination="Web.config" StackTrace="true" />
</Target>
Here comes the problem: when I'm execute MSBuild like this:
msbuild MySolution.sln /P:configuration=Site1-Stage /t:rebuild
all goes well, web.config is properly generated for the Site1-Stage configuration. However, if I run this command:
msbuild MySolution.sln /P:configuration=Site1-Stage /t:rebuild /P:DeployOnBuild=True
I get the following error:
"MySolution.sln" (rebuild target) (1) -> "MySolution\MyWebProj.csproj"
(Rebuild target) (3) -> (PreTransformWebConfig target) -> C:\Program
Files
(x86)\MSBuild\Microsoft\VisualStudio\v10.5\Web\Microsoft.Web.Publishing.targets(1399,5):
error : Copying file Web.config to
obj\Site1-Stage\TransformWebConfig\original\Web.config failed. Could
not find file 'Web.config'. [MySolution\MyWebProj.csproj]
I tried to explicitly add "AfterBuild" target into MSBuild command line:
msbuild MySolution.sln /P:configuration=Site1-Stage /t:rebuild,AfterBuild /P:DeployOnBuild=True
but it resulted in the same error.
Why do I need this: it's a very isolated example, and in reality I'm trying to setup automated publishing from TeamCity CI server. I think if I add new build step with "Visual Studio (sln)" runner BEFORE my current publishing step, that would work, it will first rebuild the project (and generate web.config) - and then publish. However, i have lots of publishing steps (around 20 now) and I would like to avoid that. My understanding is that "Publish" process does the build as part of it, so I would like to "reuse" that.
Question is: how should I modify my MSBuild command line to force config transformation to happen?
Thank you.
Maybe use "BeforeBuild"?
BTW do you have web.config included in csproj? I believe most publish activities relies on items in project rather than in folder. You can include web.config in project, while still have excluded it from source control.

MSDeploy error: library not found DbSqlPackage

Heads up: I'm a total MSDeploy noob. In fact, this is my first attempt at creating a msbuild script and I'm only recently started looking into msdeploy.
Now that that's out of the way, I'm writing a build script to compile and package my ASP.Net webforms application. The script can compile the solution, however, I'm getting the following error when attempting to package:
Microsoft.Web.Deployment.DeploymentException: The library 'Microsoft.Data.Tools.Schema.DbSqlPackage, Version=10.3.0.0, ...' could not be loaded.
I've searched the web but I can't seem to find any instances of this issue (specific to the missing DbSqlPackage.dll). I assume this has something to do with the ability to package and deploy databases referenced in the solution.
I am using MSDeploy V3 and MSBuild v4.0.30319. The Package target of the .build file is as follows:
<Target Name="Package" DependsOnTargets="Compile">
<PropertyGroup>
<PackageDir>%(PackageFile.RootDir)%(PackageFile.Directory)</PackageDir>
<Source>%(Website.FullPath)</Source>
<Destination>%(PackageFile.FullPath)</Destination>
</PropertyGroup>
<MakeDir Directories="$(PackageDir)" />
<Exec Command='"#(MsDeploy)" -verb:sync -source:iisApp="$(Source)" -dest:package="$(Destination)"' />
I am not trying to include any databases and I would be happy if there is a switch that I can set to bypass the error all together. However, if anyone knows how to FIX and not just avoid the issue, that would be preferred.
Thanks in advance.
Vinney
I tried to repair the installation of MS Web Deploy but no dice. Except, my filter terms "web deploy" turned up another item in my installed programs: "Web Deploy dbSqlPackage Provider" (or something along those lines... it's late). The build/package completes after removing this program.
It only took me half a day to find this solution... oh well!