User659414910 posted
It seems that IIS is getting confused if the text "RunAtServer" occurs anywhere in an ASPX page after a less-than sign, even if the context is completely appropriate. For example, this very tiny snippet returns "The Server Tag is not well formed":
<%@ Page Language="C#" %>
<html>
<body>
<script type="text/javascript">
if (1 < 2) alert('no bug'); // RunAtServer
</script>
</body>
</html>
As you can see, there is no server tag that is malformed. It's just javascript with a comment. This example demonstrates that it doesn't even have to be on the same line - this also triggers the error:
<%@ Page Language="C#" %>
<html>
<body>
<script type="text/javascript">
if (1 <= 2) alert('no bug');
// the text can be way down on the page.
// blahblahblahblah RunAtServer - this text triggers the error
</script>
</body>
</html>
Changing the comparison from 1 <= 2 to 1 == 1 prevents the error because the < is apparently what IIS is seeing as a server tag, WHEN it's followed by "RunAtServer". This also fails, showing that it can just
be < and not <= that triggers:
<%@ Page Language="C#" %>
<html>
<body>
<script type="text/javascript">
// this dataModel is actually being auto-generated
var dataModel = { RunAtServer: 'SomeOtherServer', Servers: ['SomeServer', 'SomeOtherServer'] };
for(var i=0; i<dataModel.Servers.length; i++) {
if (dataModel.Servers[i] == dataModel.RunAtServer) { alert('Found the server'); }
}
</script>
</body>
</html>
This does NOT fail (I changed "RunAtServer" to "RunAtSrver"):
<%@ Page Language="C#" %>
<html>
<body>
<script type="text/javascript">
// this dataModel is actually being auto-generated
var dataModel = { RunAtSrver: 'SomeOtherServer', Servers: ['SomeServer', 'SomeOtherServer'] };
for(var i=0; i<dataModel.Servers.length; i++) {
if (dataModel.Servers[i] == dataModel['RunAtSrver']) { alert('Found the server'); }
}
</script>
</body>
</html>
Also, the bug can be prevented by putting a greater-than sign in a comment before the use of RunAtServer:
<%@ Page Language="C#" %>
<html>
<body>
<script type="text/javascript">
// this dataModel is actually being auto-generated
var dataModel = { RunAtServer: 'SomeOtherServer', Servers: ['SomeServer', 'SomeOtherServer'] };
for(var i=0; i<dataModel.Servers.length; i++) {
// > This prevents the bug from occurring
if (dataModel.Servers[i] == dataModel['RunAtServer']) { alert('Found the server'); }
}
</script>
</body>
</html>
This may seem like a minor issue, and admittedly it probably is in the grand scheme of things.. but it's pretty inconvenient because in my case "RunAtServer" is actually a data model property that is being automatically generated and is used
throughout my code base, so I'm going to have to change my data model in a lot of places. If this was generated by a third party API or something, I'd have to go thru convulsions to make it work, such as adding the // > in a comment after
every use of a less-than sign, or building the variable name from parts (eg var vName = ['Run', 'At', 'Server'].join('')]) and then referencing the variable indirectly every time (dataModel[vName]).