msdeploy Parameters.xml deploy cannot set a value on node type 'Element' - msdeploy

For a load balanced web application I want to remove or add an element in web.config with setparameters.xml. Changing Attributes is working fine, but when I try to remove an entire element the following error appear in the verbose log from the generated cmd file during deploy: cannot set a value on node type 'Element'.
My config is as following (I want to remove the endpoint: name="A")
<system.serviceModel>
<client>
<endpoint name="A" address="soap.udp://ip.adress" />
<endpoint name="B" address="soap.udp://ip.adress" />
</client>
And a Parameters.xml with the following:
<parameter name="cacheFlushEndepunkt" description="cacheFlush" defaultValue="" tags="">
<parameterValidation kind="AllowEmpty"/>
<parameterEntry kind="XmlFile" scope="Web\.config$" match="/configuration/system.serviceModel/client/endpoint[#name='A']"/>
</parameter>
Is it possible to remove or add elements in web.config with ms deploy and setparameters?

Your XPATH in match attribute of parameterEntry element seems to be not correct. Use following
//system.serviceModel/client/endpoint[#name='A']
or the same
//configuration/system.serviceModel/client/endpoint[#name='A']
And section in parameters.xml to remove XML element from web.config looks like:
<parameter name="removeDnoaReporting" description="DotNetOpenAuth section" defaultValue="" >
<parameterValidation kind="AllowEmpty" />
<parameterEntry kind="XmlFile" scope="Web\.config$" match="//dotNetOpenAuth/reporting" />
</parameter>

Related

Using NLog to log to MySql database using Pomelo provider in an ASP .Net Core 5 Web API

I have an ASP .Net Core Web API using NLog, and I am trying to configure it to log to a MySQL database. I am using Pomelo in my app to talk to MySql.
In the nlog.config file, I have:
<target name="db"
xsi:type="Database"
dbProvider="Pomelo.EntityFrameworkCore.MySql, Pomelo.EntityFrameworkCore"
connectionString="blah blah blah"
commandType="StoredProcedure"
commandText="`InsertLog`"
>
<parameter name="machineName" layout="${machinename}" />
<parameter name="logged" layout="${date}" />
<parameter name="logLevel" layout="${level}" />
<parameter name="message" layout="${message}" />
<parameter name="logger" layout="${logger}" />
<parameter name="properties" layout="${all-event-properties:separator=|}" />
<parameter name="callsite" layout="${callsite:fileName:true}" />
<parameter name="exception" layout="${exception:tostring}" />
<parameter name="callsiteLineNumber" layout="${callsite-linenumber}" />
<parameter name="stackTrace" layout="${stacktrace}" />
</target>
However, it's giving an error "Could not load file or assembly 'Pomelo.EntityFrameworkCore"
Do I have the wrong dbProvider? Does Nlog not work with Pomelo?
I followed lauxjpn's comment, and it worked. Thanks lauxjpn!

MSDeploy setParameter.xml not transforming web.config

In my "myconfig" config profile transform for web.config i have this under appSettings:
<add key="my.config" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" value="derp" />
When I msbuild with this transform the value is transformed correctly. Now I want to build an msdeploy package and transform this value at deploy time.
I drop this parameters.xml in my project root:
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<parameter name="my.config" description="sdfsdfsdfsd" defaultValue="fart">
<parameterEntry kind="XmlFile"
scope="\\Web\.config$"
match="/configuration/appSettings/add[#my.config]/#value/text()" />
</parameter>
</parameters>
I build my package
msbuild app.csproj /T:Package /p:Configuration=myconfigprofile;PackageLocation=mydeploy.zip
I look at mydeploy.SetParameters.xml
<?xml version="1.0" encoding="utf-8"?>
<parameters>
<setParameter name="IIS Web Application Name" value="Default Web Site/myApp_deploy" />
<setParameter name="my.config" value="fart" />
</parameters>
Then I go into parameters.xml inside of mydeploy.zip and see its there too:
<parameters>
<parameter name="my.config" description="sdkflsdjfldfj" defaultValue="fart">
<parameterEntry kind="XmlFile" scope="\\Web\.config$" match="/configuration/appSettings/add[#name='my.config']/#value/text()" />
</parameter>
</parameters>
looks good so far, then i deploy:
mydeploy.deploy.cmd /Y /M:server1
I look at web.config on the deploy server and the value is not transformed. I see no errors either, how do i debug this even?
When I run msbuild with parameters.xml present what magic happens there? How is the package preps to be able to transform web.config via parameters to web deploy?
This:
add[#name='my.config']
Had to be changed to this:
add[#key='my.config']
But the bigger question remains, how do I debug? I had to try a million times and just guess because I had zero errors/logs to help troubleshoot this. Is there verbose logging or some kind of validator or anything at all?
For debugging technet gave me this to try:
msbuild MyProject.proj /t:go /fl /flp:logfile=MyProjectOutput.log;verbosity=diagnostic
If you are using MSDeploy you can get the full output of the deployment by using the following:
msdeploy -verb:sync -source:dirpath=C:\WebDeployDemo\Src -dest:dirpath=C:\WebDeployDemo\Dst -setParamFile=C:\WebDeployDemo\ParameterFile.xml -verbose >msdeploysync-verbose.log
This helps with VSTS WebRM deployment debugging if you use the -verbose flag.
Sources:
https://learn.microsoft.com/en-us/iis/publish/troubleshooting-web-deploy/troubleshooting-web-deploy
https://blogs.msdn.microsoft.com/spike/2012/10/12/using-msdeploy-to-update-and-remove-sections-in-web-config-a-simple-example/

TFS variables for connection string

I have continous integration in tfs project. I want to replace connection string to my production db on release, but all the information on the web is confusing. I created parameters.xml with this:
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<parameter name="connectionString" description="connectionString" defaultvalue="(localdb)\MSSQLLocalDB;InitialCatalog=BlogsPostsLocalDb;Integrated Security=true;" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="What to write here?" />
</parameter>
</parameters>
In TFS, in my App Deploy task I can see SetParameters File option, so I suspect that I have to use that, but I don't understand how to tell it which parameter in Web.config belongs to the parameter in parameters.xml.
In my Web.config I need to replace static path with the one in parameters.xml. My Web.config:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="Data Source=(localdb)\MSSQLLocalDB;InitialCatalog=BlogsPostsLocalDb;Integrated Security=true;" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
EDIT:
I used a tool to create parameters.xml which now looks like this:
<parameters>
<parameter name="ConnectionString" description="Description for ConnectionString" defaultvalue="__CONNECTIONSTRING__" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[#key='ConnectionString']/#value" />
</parameter>
</parameters>
My web.config:
<appSettings>
<add key="ConnectionString" value="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=BlogsPostsTestDb;Integrated Security=True" />
</appSettings>
And in my context I do this:
public BlogsPostsContext() : base(WebConfigurationManager.AppSettings["ConnectionString"]) { }
In TFS I set variable for relase
Name | Value
ConnectionString | Data Source=WIN-7ADV5BGRBE3\SQLEXPRESS;Initial Catalog=BlogsPostsDb;Integrated Security=True
Unfortunately when I do a release and look inside web.config on my server I can only see <add key="ConnectionString" value="__CONNECTIONSTRING__" />
And the parameters.xml:
<parameters>
<parameter name="ConnectionString" description="Description for ConnectionString" defaultvalue="__CONNECTIONSTRING__" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[#key='ConnectionString']/#value" />
</parameter>
</parameters>
MsBuild Arguments:
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\"
A [project name].SetParameters.xml file is generated when you build a web application project.
This provides a set of parameter values to the MSDeploy.exe command.
You can update the values in this file and pass it to Web Deploy as a
command-line parameter when you deploy your web package.
Since SetParameters.xml file is dynamically generated from your web application project file and any configuration files within your project.
You could also parameterize additional settings by adding a parameters.xml file to your project. Below entry uses an XML Path Language (XPath) query to locate and parameterize the endpoint URL of the ContactService Windows Communication Foundation (WCF) service in the web.config file.
<parameters>
<parameter name="ContactService Service Endpoint Address"
description="Specify the endpoint URL for the ContactService WCF
service in the destination environment"
defaultValue="http://localhost/ContactManagerService">
<parameterEntry kind="XmlFile" scope="Web.config"
match="/configuration/system.serviceModel/client
/endpoint[#name='BasicHttpBinding_IContactService']
/#address" />
</parameter>
</parameters>
The WPP also adds a corresponding entry to the SetParameters.xml file that gets generated alongside the deployment package.
<parameters>
...
<setParameter
name="ContactService Service Endpoint Address"
value="http://localhost/ContactManagerService" />
...
</parameters>
For how to tell it which parameter in Web.config belongs to the parameter in parameters.xml, you need to use match entry to do this. More detail info please refer this tutorial: Configuring Parameters for Web Package Deployment
I had a similar problem, I am using ASP.Net and IIS application in visual studio i created a configuration for example Test for any cpu then i publish a IIS file called test.pubxml (right click on project click publish), That file will contain the connection string from your web.config file , Then you right-click on the file you have created (test.pubxml) and select add web-transform file add the following iy you want to transform the connection string.
<connectionStrings>
<add name="test" connectionString="Data Source=(localdb)\MSSQLLocalDB;InitialCatalog=BlogsPostsLocalDb;Integrated Security=true;" xdt:Transform="SetAttributes(connectionString)" xdt:Locator="Match(name)" />
</connectionStrings>
Now you have a file that will do the exact same things as parameters.xml file.
In your build defition add the following to ms arguments
/p:DeployOnBuild=true;PublishProfile=test.pubxml;Configuration=Test;
That will build a .zip package,
In your Release Definition
In your deploy step, Add the following to your Web Deploy Parameter File input
Path/Path/test.SetParameters.xml
That Will deploy the website with transformed connection string.
I know its a lot but you can follow this blog its really helpfull Colin
Following articles about parameters.xml mislead me. It turns out that all I had to do to make it work was to follow instructions inside Web.Release.Config.
This is what I added inside Web.config:
<connectionStrings>
<add name="BlogsPostsDb"
providerName="System.Data.SqlClient"
connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=BlogsPostsTestDb;Integrated Security=True"/>
</connectionStrings>
And this is what I added inside Web.Release.Config:
<connectionStrings>
<add name="BlogsPostsDb"
connectionString="Data Source=myServerInstance;Initial Catalog=BlogsPostsDb;User ID=*********;Password=******;"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
Now it makes sense. As long as the names match in both configs, they will be replaced. I also had to tell my context which connection string I want to use:
public BlogsPostsContext() : base("BlogsPostsDb") { }

Remove Parameters from the generated setParameters.xml

Is there a way to remove parameters from the generated SetParameters.xml within an MSDeploy package.
My Parameters.xml looks like this:
<parameter name="Server" defaultValue="" />
<parameter name="Directory" defaultValue="" />
<parameter name="Service URL" defaultValue="http://{Server}/{Directory}/Services/GeneralIntegrationService.svc" tags="hidden">
<parameterEntry kind="XmlFile" scope="Web.config" match="//system.serviceModel/client/endpoint[#name='BasicHttpBinding_IGeneralIntegrationService']/#address" />
what I want is the generated SetParameters.xml to only contain the first 2 parameters.
I've reviewed this question:
Can MSBuild exclude "Hidden" Web Deploy parameters from the generated SetParameters.xml?
however, I can't get my head around how the .targets file is supposed to set up. Can someone detail a complete example of what the parameters.xml and the .targets file looks like. Also, is there anything I need to set in the build properties of the .targets file?
I don't think the SetParameters-method is designed to be used that way. I would use config-transforms for parameters you want to hide from the person installing the application.
Edit
Actually, for your scenario, you could do a "search and replace" in the Web.config to get the desired result
In your parameters.xml
<parameters>
<parameter name="Server" description="" defaultValue="" tags="">
<parameterEntry kind="TextFile" scope="\\web.config$" match="##Server##" />
</parameter>
<parameter name="Directory" description="" defaultValue="" tags="">
<parameterEntry kind="TextFile" scope="\\web.config$" match="##Directory##" />
</parameter>
</parameters>
And where you need the endpoint address in the Web.Config, just put the URL like this:
http://##Server##/##Directory##/Services/GeneralIntegrationService.svc

.NET Web Deployment Tool with log4Net: Not overwriting logs

I'm using the Web Deployment Tool to build and release an MVC site from VS 2010 to a server running IIS. I also have log4net logging to a subdirectory off of the root of the web application I'm deploying to. I already figured out how to keep write permissions intact when deploying with this tool on that directory, but now I'm running into the problem that I'd rather not lose the logs when deploying, and also, the deploy is failing because the log file that log4net is using is "used by another process" (presumably w3wp) and won't let the deploy continue.
So, I'd like to preserve the log files and not delete or overwrite them, for auditing purposes. Is there a way to do that within the confines of the Web Deployment Tool?
EDIT: Here's the applicable bits of the log4net configuration, in Web.Config.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net" />
</configSections>
<log4net>
<appender name="RollingLog" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Logs\Log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Composite" />
<maxSizeRollBackups value="20" />
<maximumFileSize value="10MB" />
<datePattern value="yyyyMMdd" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="{%level}%date{MM/dd HH:mm:ss} - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLog" />
</root>
</log4net>
</configuration>
Found it by hunting around: there is a "skip" parameter you can tack on to the command when you call the pre-packaged deploy script. You HAVE to use a regular old CMD prompt for this; Powershell's crazy escaping of quotes makes it near-impossible to get right, so I gave up. Anyway, here's the end result I came up with:
.\MyProject.deploy.cmd /Y /M:MyServerName "-skip:skipAction=Delete,objectName=filePath,absolutePath=Logs"
"MyProject.deploy.cmd" being the name of the prepackaged deploy command, "MyServerName" being the name of the server I was deploying to, and "Logs" being the name of the folder I wanted to skip. This command seems to leave alone that Logs directory and deploy anything else that matters.
Source where I started to hone in on things: http://blogs.iis.net/msdeploy/archive/2009/04/23/what-has-changed-about-skip-replace-rules-in-rc.aspx
Set locking model of your appender to minimal lock and everything will be fine:
<appender name="RollingLog" type="log4net.Appender.RollingFileAppender">
...
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
...
</appender>
log4net.Appender.FileAppender (see remarks)

Resources