Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply VS2010 web.config transformation to an element with a namespace attribute?

I'd like to use the new VS2010 web.config transformation feature to change the connection string within the nhibernate configuration in my web.config file. The relevant snippet is something like this:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
  </configSections>

  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
      <property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
      <property name="connection.connection_string">(test connection string)</property>
      <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
...

I've tried the following transformation without success:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
        <session-factory>
            <property name="connection.connection_string" xdt:Transform="Replace">(production connection string)</property>
        </session-factory>
    </hibernate-configuration>
</configuration>

The problem seems to be in the xmlns attribute of the nhibernate-configuration element.

What should be the correct transformation to replace (test connection string) with (production connection string) during deployment?

like image 266
gschuager Avatar asked Jun 17 '10 14:06

gschuager


3 Answers

I recently encountered the same issue - it was solved by placing explicit namespace prefixes in the transform file

<configuration
               xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"
               xmlns:hib="urn:nhibernate-configuration-2.2"
              >
    <hib:hibernate-configuration>
        <hib:session-factory>
            <hib:property name="connection.connection_string" xdt:Transform="Replace">(production connection string)</hib:property>
        </hib:session-factory>
    </hib:hibernate-configuration>
</configuration>

The resulting transformed web.config file was thankfully free of the namespace prefixes (i.e. it left the nhibernate namespace declaration in the same spot as it was in the original web.config file and correctly named all the nodes)

like image 89
Andrew Patterson Avatar answered Nov 03 '22 21:11

Andrew Patterson


The answer may be a bit late, but since I needed this as well, I figured I would post an answer that worked for me in the event anyone else stumbles upon this question.

You need to use the xdt:Locator in combination with an xpath expression to get the correct node. So something like this should work.

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
   <session-factory>
      <property name="connection.connection_string" xdt:Locator="XPath(//*[local-name()='hibernate-configuration']//*[local-name()='property'][@name='connection.connection_string'])" xdt:Transform="Replace">(production connection string)</property>
   </session-factory>
</hibernate-configuration>

There may be a better xpath expression, but this is what worked for me.

The only issue, which isn't that big a deal, is the replaced node will have a namespace redeclared on the node. So the replaced node will actually look like this in the final output.

<property name="connection.connection_string" xmlns="urn:nhibernate-configuration-2.2">(production connection string)</property>
like image 7
bgrebil Avatar answered Nov 03 '22 21:11

bgrebil


If all you are trying to do is transform the connection string, do not use the transformation mechanism. Instead, in your web.config or app.config, reference this property

connection.connection_string_name

instead of this one:

connection.connection_string

This allows you to reference the connection string defined in the ConnectionStrings section, which is transformed in the usual way.

eg in web.config, use this code:

<connectionStrings>
  <add name="DefaultConnection" connectionString="server=MYSERVER; Integrated Security=SSPI; database=MYDATABASE"/>
</connectionStrings>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string_name">DefaultConnection</property>
    <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
    <property name="current_session_context_class">web</property>
    <property name="show_sql">true</property>
  </session-factory>
</hibernate-configuration>
like image 1
Brian Leeming Avatar answered Nov 03 '22 21:11

Brian Leeming