TFS variables for connection string - asp.net

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") { }

Related

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/

ASP.NET MVC with Entity Framework connection string and context not works while creating database

I have some problems with my ASP.NET MVC project, using Entity Framework. The problem is about connection strings (I searched it on web but not works yet)
These are my scenarios:
The ASP.NET MVC project has a class called DbData extending DbContext. A controller calls a new instance of this class and call SaveChanges to create the database. I'm having problem with database creation.
If I run without specific configuration and inspect context instance, I get this exception
Invalid operation. The connection is closed
The data source is .\SQLEXPRESS by dafault. Result cannot create the database
If I try to use a connection string with a specific SQL Server database with name setting in web.config and name in DbData : base("name = dbconn"), I get an error that "dbconn" doesn't exist in web.config.
the code:
public class DbData : DbContext
{
public DbData()
//: base("Name=dbconn")
{
}
public DbSet<Info> infos {get;set;}
}
this is the web config ( trying to use a custom connection string )
<add name="dbconn" providerName="System.Data.SqlClient" connectionString="Server=MYPC\SQL2012;MultipleActiveResultSets=True;Database=MvcDB;Persist Security Info=True;Integrated Security=SSPI;" />
EntityFramework section into web.config:
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
I'm going crazy. Help me please. Thanks
If you want to use your Default LocalDB (sqlExpress in your case) then your tag in the should look the following:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="localdbinstancename" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
If you are wanting to use a specific database server (with a configured connection string) your config file will look something like:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" >
<parameters>
<parameter value="Data Source=.; Integrated Security=True; MultipleActiveResultSets=True" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
*The important difference is the connectionfactory reference in the tag.
*The parameter tag may not be necessary depending on how the connection string is specified.

Web.config connectionString transforms not working when using an external config file

Ok, I am using an external config file for my connection strings so each individual developer can have their own strings while developing. Normally, each dev has a different environment but we all publish to the same servers via web.release.config transforms.
However, when I publish from VS, it's not transforming from the web.release.config for the conn strings. I think it's because if you have the configSource attribute set to use an external config it ignores the transform.
Here's my web.config:
<connectionStrings configSource="userConn.config" />
And here's my userConn.config:
<?xml version="1.0"?>
<connectionStrings>
<add name="DefaultConnection"
providerName="System.Data.SqlClient"
connectionString="Data Source=XXXX;Initial Catalog=XXXX;user id=XXXX;password=XXXX;" />
<add name="ExtVariablesEntities"
providerName="System.Data.EntityClient" connectionString="metadata=res://*/Models.XXXX.csdl|res://*/Models.XXXX.ssdl|res://*/Models.ExtVariables.msl;provider=System.Data.SqlClient;provider connection string="data source=XXXX;initial catalog=XXXX;user id=XXXX;password=XXXX;MultipleActiveResultSets=True;App=EntityFramework;"" />
</connectionStrings>
After publishing, opening the actual web.config that made it to the server, it still has:
<connectionStrings configSource="userConn.config" />
Is there a workaround for this? I've had this setup before I just don't remember what the trick is.
Just an FYI that I was able to solve this by following this article: https://jshowers.com/simple-web-config-transforms-for-configuration-elements-that-use-configsource-and-external-files/
You end up with 3 custom config files - whatever you want to call them for dev, test and prod lets say. Then you will have 3 web config files dev, test and prod (these are your web config transform files) where you simply say:
<appSettings xdt:Transform="Replace" configSource="path.to.custom.config.file.depending.on.env">

Oracle.ManagedDataAccess: TNS:could not resolve the connect identifier specified

I'm getting the following error while trying to connect to an Oracle database from a new ASP.NET MVC 4 application: "ORA-12154: TNS:could not resolve the connect identifier specified". I'm using the Oracle.ManagedDataAccess DLL (version 4.121.1.0) to try to connect to an Oracle 10g database. Here's the thing - I have an integration test assembly that is successfully connecting to the database using this minimal App.config:
<connectionStrings>
<add name="OracleConnection" connectionString="DATA SOURCE=TNS_NAME;PASSWORD=xxx;PERSIST SECURITY INFO=True;USER ID=xxx" providerName="Oracle.ManagedDataAccess.Client" />
</connectionStrings>
However, if I try to run my web app with all the crazy Web.config settings, I'm getting the error "ORA-12154: TNS:could not resolve the connect identifier specified". What am I doing wrong? Why is my config for the integration test assembly so simple and the Web.config so complex? Here's the pertinent sections of my Web.config (taken from Deploying and Configuring ODP.NET to work without installation with Entity Framework):
custom configSection:
<configSections>
<section name="oracle.manageddataaccess.client"
type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</configSections>
the corresponding config section:
<oracle.manageddataaccess.client>
<version number="*">
<edmMappings>
<edmMapping dataType="number">
<add name="bool" precision="1"/>
<add name="byte" precision="2" />
<add name="int16" precision="5" />
</edmMapping>
</edmMappings>
</version>
</oracle.manageddataaccess.client>
custom system.data node:
<system.data>
<DbProviderFactories>
Remove in case this is already defined in machine.config
<remove invariant="Oracle.DataAccess.Client" />
<remove invariant="Oracle.ManagedDataAccess.Client" />
<add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client"
description="Oracle Data Provider for .NET, Managed Driver"
type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
EntityFramework node:
<entityFramework>
<defaultConnectionFactory type="Victoria.Data.OracleConnectionFactory, EntityFramework" />
</entityFramework>
Update 1: After reading through http://docs.oracle.com/cd/E16655_01/win.121/e17732/featConfig.htm#ODPNT8161, I tried modifying my Web.config oracle.manageddataaccess.client to the following and it works. However, it doesn't seem right to have the connectionString node referencing the TNS name AND this extra reference to the same TNS Names file.
<oracle.manageddataaccess.client>
<version number="*">
<dataSources>
<dataSource alias="SIEBMATS" descriptor="(DESCRIPTION=(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = xxx.yyy.zzz)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = siebmats)))" />
</dataSources>
<edmMappings>
<edmMapping dataType="number">
<add name="bool" precision="1"/>
<add name="byte" precision="2" />
<add name="int16" precision="5" />
</edmMapping>
</edmMappings>
</version>
</oracle.manageddataaccess.client>
One thing you can try is having the connection string like so:
connectionString="Data Source=//SERVER:PORT/INSTANCE_NAME;USER=XXX;PASSWORD=XXX".
Useful references here:
http://www.connectionstrings.com/oracle/
http://docs.oracle.com/cd/E51173_01/win.122/e17732/featConnecting.htm#ODPNT169
This has also helped me while having problems with EF:
Deploying and Configuring ODP.NET to work without installation with Entity Framework
Hope to have helped.
My problem was in incorrect/incomplete Oracle Driver version, had 11.2.0 installed. I add another 12.2.0 version, didn't change anything in web.config and it worked as charm
I suggest to try the solution proposed by #kolbasov in another thread but about the same problem: https://stackoverflow.com/a/20050462/9390179
It worked for me:
<oracle.manageddataaccess.client>
<version number="*">
<settings>
<setting name="TNS_ADMIN" value="C:\Oracle\product\11.1.0\client_1\network\admin" />
</settings>
</version>
</oracle.manageddataaccess.client>

Transform of ELMAH string when publishing to production server name not working

I am running Visual Studio 2010, using an ASP.Net forms application.I am trying to transform XMl on build but it is not working.
In my config section I have the following:
<elmah>
<security allowRemoteAccess="yes" />
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionString="Data Source=TestServer;Initial Catalog=OnlineApplication;Trusted_Connection=True" />
<errorMail from="emhelp#server.edu" to="person#test.com" subject=" Exception" async="true" smtpserver="smtpgate.server.edu" />
I am trying to get it the ELMAH server name to transform when I publish to production via web.config.production xml transformation. All of my other settings for the app settings and connection strings work fine.
I have the following in my web.production.config:
<add type="Elmah.SqlErrorLog, Elmah"
connectionString="Server=ProductionServer;Initial Catalog=OnlineApplication;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(type)"/>
</elmah>
It doesn't complain but it also does't transform the text. What do I need to change to make the file transform on build/publish.
Since is only one errorLog tag, you can use Replace instead of SetAttributes with a locator. Also note that you have to use the actual tag name, not <add>.
<errorLog type="Elmah.SqlErrorLog, Elmah"
connectionString="Server=ProductionServer;Initial Catalog=OnlineApplication;Integrated Security=True"
xdt:Transform="Replace"/>

Resources