46

I have a web.config rewrite rule specified to move all traffic to https. The rule works, but I don't want SSL required while I am debugging. I have a bunch of web.release.config transformations being done already that work on publish so I decided to put a rewrite rule in there. The problem is that the rewrite rule isn't being transformed like the rest of the settings. Here is the web.config setup:

<system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true"/>

    <rewrite></rewrite>
</system.webServer>

And here is the transformation being done:

  <system.webServer>
<rewrite>
  <rules>
    <rule name="Redirect HTTP to HTTPS" stopProcessing="true">
      <match url="(.*)"/>
      <conditions>
        <add input="{HTTPS}" pattern="^OFF$"/>
      </conditions>
      <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther"/>
    </rule>
  </rules>
</rewrite></system.webServer>

If I just copy the rewrite rule to the web.config it works fine. Does anyone out there have any ideas why web.Release.config transforms aren't working for only this section?

Matthew Kruskamp
  • 1,887
  • 2
  • 14
  • 31
  • I would also love to know what's up with this. The transform doesn't seem to behave like it should. – Dusda Aug 10 '11 at 20:27

4 Answers4

45

Transformation will only happen if you put proper xdt attributes on the elements that need to be transformed. Try adding an xdt:Transform attribute to your release config:

<system.webServer xdt:Transform="Replace">
    <!-- the rest of your element goes here -->
</system.webServer>

That will tell the transformation engine that the entire system.webServer element from Web.config needs to be replaced with the one from Web.Release.config.

The transformation engine will silently ignore any elements that do not have xdt attributes.

Obligatory link to MSDN.

Lobstrosity
  • 3,928
  • 29
  • 23
  • Hey, thanks a ton. I saw some examples that didn't explicitly put the transform. This is a huge lifesaver. I should check the documentation better in the future, but I appreciate it. – Matthew Kruskamp Aug 20 '11 at 00:34
  • I'd +4654654564324 if I could. I've wondered for a while why I could never get this to work. It'd be nice if the transformation engine would spit out a warning when ignoring an element. – David Murdoch Aug 26 '11 at 15:13
  • 40
    Extra note for people with more complicated files. You can put the `xdt:Transform` element on the `` tag and change it to Insert like this: `` which will preserve any other tags in your `` section. – Michael Dunlap Jan 19 '13 at 00:12
  • 5
    I hate web.config transformations. Who designs this. – John Shedletsky Jun 11 '15 at 20:14
  • 4
    Actually `web.config` transformations are very slick... some people are just stuck in the past... – Serj Sagan Nov 30 '15 at 01:09
  • 2
    Whats the good schema to use? I have 'http://schemas.microsoft.com/XML-Document-Transform' and VS 2015 tells me that xdt:Transform is not declared on – Stephane May 02 '17 at 18:36
  • 1
    @Stephane looks like the schema likes the Transform in parent `` but does not expect it in `` or `` underneath. But others report it works anyway. – SushiGuy Aug 24 '17 at 14:19
33

Another way to go would be to put in a rewrite condition that negates if you are on localhost:

<conditions>
    <add input="{HTTP_HOST}" pattern="localhost" negate="true"/>
</conditions>
citronas
  • 19,035
  • 27
  • 96
  • 164
  • 2
    Awesome solution. Worth noting if you're using Chrome - Chrome caches the redirect - so you may need to clear the cache: http://superuser.com/questions/304589/how-can-i-make-chrome-stop-caching-redirects – Chris Nevill Aug 09 '16 at 14:36
10
<system.webServer>
    <rewrite>
        <rules xdt:Transform="Replace">
            <clear />
            <rule name="Redirect HTTP to HTTPS" stopProcessing="true">
              <match url="(.*)" />
              <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_HOST}" pattern="localhost(:\d+)?" negate="true" />
                <add input="{HTTP_HOST}" pattern="127\.0\.0\.1(:\d+)?" negate="true" />
                <add input="{HTTPS}" pattern="OFF" />
              </conditions>
              <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther" />
            </rule>
        </rules>          
    </rewrite>
</system.webServer>
Ray Linder
  • 129
  • 2
  • 7
2

Summing up other answers here, we discovered the obvious: "Replace" will only replace a node, not "Insert" it (thanks DigitalD for the right track). The rest of our transformation files use replace so we opted for an empty tag in our base web.config (the one that gets transformed).

<system.webServer>
...other tags here that do not get transformed...
<rewrite />
</system.webServer>

Ideally there would be "Overwrite" which would Insert or Replace (or Remove and Insert).

BlackjacketMack
  • 5,472
  • 28
  • 32