I'm looking to slowly convert a Node.js
application over to ASP.NET WebAPI 2.0
. I'm currently using IIS
and will stick with IIS
. So, I would like to host them on the same server but direct some URIs over to the new platform.
How would I do this in the web.config
? The current web.config
for node.js
looks like so:
<configuration>
<system.webServer>
<handlers>
<!-- indicates that the app.js file is a node.js application
to be handled by the iisnode module -->
<add name="iisnode" path="beta/app.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<!-- Don't interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^beta/app.js\/debug[\/]?" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="beta/public{REQUEST_URI}" />
</rule>
<!-- All other URLs are mapped to the Node.js application entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
</conditions>
<action type="Rewrite" url="beta/app.js" />
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Detailed"/>
</system.webServer>
</configuration>
The file structure is:
- web.config (the one shown above)
-> node
- app.js
- ...
-> webapi
- web.config
- global.asax
- ...
I was thinking that I should be writing a new rule which lists the URIs to go to the WebAPI
. But, I'm not quite sure how to do that. My guess is that I would add a condition for each URI
with the input
attribute. I was also thinking I should point to the ASP.NET WebAPI
project but I am even more clueless how I should go about doing that since Node.js
I'm just pointing at the app.js
file.
OK, this is what I ended up doing. It was actually pretty straight forward. But when you are not familiar with IIS it can be daunting.
I put the original web.config
in with the node
directory. I think the iisnode
handler interferes with WebAPI
config if you don't. So, the new node.js
web.config
in the node
directory would look like this:
<configuration>
<system.webServer>
<handlers>
<!-- indicates that the app.js file is a node.js application
to be handled by the iisnode module -->
<add name="iisnode" path="app.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^app.js\/debug[\/]?" />
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Detailed"/>
</system.webServer>
</configuration>
For root web.config
I made it point to static files directly, bypassing node.js
. Which means I'm going to have to write some custom code to handle rewrites for gzipped
files - I'll figure that out later. I also added the attribute stopProcessing
to each rewrite
rule
. This was also messing up the code, as it wouldn't actually rewrite where I wanted it too, since the rewrite would be overwritten. Note that the accept
versioning header hasn't actually been tested yet - I don't have any reason to believe it wouldn't work though. The last rewrite
points all uri
s to the webapi
app by default.
In the WebAPI
project I had to route all my routes to webapi/api
since it isn't in the root folder. After I migrate everything from node.js
I will probably make the webapi
directory the root folder for the project so it won't need the webapi
in my routing anymore. But this is all hidden from the client.
So here's the actual code:
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- test item for webapi folder -->
<rule name="StaticContent2" stopProcessing="true" >
<conditions>
<add input="{REQUEST_URI}" pattern="^/def" />
</conditions>
<action type="Rewrite" url="webapi{REQUEST_URI}" />
</rule>
<!-- rewrite static items which exist on node -->
<rule name="Node Static" stopProcessing="true" >
<conditions>
<add input="{REQUEST_URI}" pattern=".*\.[A-Za-z2]{2,5}$" />
</conditions>
<action type="Rewrite" url="node/public{REQUEST_URI}" />
</rule>
<rule name="WebAPI Version 2" stopProcessing="true">
<conditions>
<add
input="{HEADER_ACCEPT}"
pattern="vnd.fieldops.v2"
ignoreCase="true"
/>
</conditions>
<action type="Rewrite" url="webapi{REQUEST_URI}" />
</rule>
<!-- rewrite to node for dynamic items -->
<rule name="Node Dynamic" stopProcessing="true" >
<conditions>
<add
input="{REQUEST_URI}"
pattern="^/api/(dealerservicereports|chat|dealers|dealerequipment|dealercloseout|publications|tokens|users|\?)"
ignoreCase="true"
/>
</conditions>
<action type="Rewrite" url="node/app.js" />
</rule>
<!-- rewrite everything else to webapi -->
<rule name="WebAPI Dynamic" stopProcessing="true" >
<action type="Rewrite" url="webapi{REQUEST_URI}" />
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Detailed"/>
</system.webServer>
</configuration>