Integrating ASP.NET Core With Webforms Using IIS URL Rewrite

I'm currently updating a legacy ASP.NET WebForms application to ASP.NET Core. Because big rewrites (almost) never work, it's a case of migrating sections of the site one at a time, having WebForms pass specific requests to ASP.NET Core, with no change to the end user's experience. How, you ask? With a couple of IIS tools and a sprinkle of web.config entries.

ASP.NET Core can be served via IIS, with IIS acting as a reverse proxy. Requests come into IIS, the ASPNetCoreModule routes them to Kestrel, and returns the results. In my scenario, the ASP.NET Core application is only ever accessible via WebForms, so it takes a little bit of setting up. Here's how.

Setting up IIS

AspNetCoreModule

Firstly, you need the AspNetCoreModule. Luckily, you probably already have it - Visual Studio installs it into IIS for you. To check, open IIS Manager, and at the server level open Modules in the IIS section - you should see it listed there. If not, you can install it via the ASP.NET Core Server Hosting Bundle - here's a direct link to download the installer: download!

Application Request Routing

Next, you need the Application Request Routing module to route requests rewritten by the URL Rewrite module (try saying that ten times fast). You can install this via IIS Manager - click Get New Web Platform Components in the right-hand column to open the Web Platform Installer, then search for ARR, and look for version 3.0:

ARR

Once that's installed, open Application Request Routing in the server-level IIS section (you may need to close and re-open IIS to see the icon), click Server Proxy Settings, check Enable proxy, and click Apply:

ARR

URL Rewrite

Finally, you need the URL Rewrite module. This you can also install via the Web Platform Installer - just search for rewrite, and look for version 2.0:

UrlRewrite

Setting up ASP.NET Core

Firstly, you need IIS integration in your application. This is super easy, and you probably already have it - it's simply a call to UseIISIntegration() on the WebHostBuilder in your Program.cs. If you're missing it, UseIISIntegration is an extension method from the Microsoft.AspNetCore.Server.IISIntegration NuGet package.

That one line is all you need in your ASP.NET Core application - now you just publish the project. You can use a File System publish, go via WebDeploy, or whatever you prefer.

Finally, set up an IIS website pointing to your ASP.NET Core publish directory. Because this website will be accessed via WebForms only, bind it to a non-public port number - I'll use 1234 for our example:

CoreBindings

Setting up WebForms

Finally, you need to tell WebForms to send the appropriate requests to ASP.NET Core.

You can do this with rules in your web.config which configure the URL Rewrite module. For example, say you've migrated your news pages to an ASP.NET Core NewsController, the following rules tell IIS what to do with requests for the ASP.NET Core 'news' section:

<system.webServer>
 <rewrite>
  <rules>
   <rule name="AspNetCoreContent" stopProcessing="true">
    <match url="^content/(.+)$" ignoreCase="true" />
    <action type="Rewrite" url="http://localhost:1234/content/{R:1}" />
   </rule>
   <rule name="AspNetCoreNews" stopProcessing="true">
    <match url="^news(.*)$" ignoreCase="true" />
    <action type="Rewrite" url="http://localhost:1234/News{R:1}" />
   </rule>
  </rules>
 </rewrite>
</system.webServer>

Both rules have the same pattern: they both capture requests with URLs beginning with particular strings (content/ and news, respectively), and rewrite them to requests on port 1234 on the local machine. The {R:1} reference in the rewritten URLs is replaced with the captured group from the regular expression which matched the request URL. The content/ rule allows the ASP.NET Core application to reference static files in a content directory in its wwwroot, and have IIS route those requests back to the appropriate place.

And that's it! A page-by-page migration is underway with a few simple steps.

Print | posted @ Saturday, March 25, 2017 11:43 AM

Comments on this entry:

Gravatar # re: Integrating ASP.NET Core With Webforms Using IIS URL Rewrite
by Gavin Sutherland at 4/10/2017 9:22 AM

Hi Steve ... this is a helpful article. I have a couple questions though:

1) Using this approach how do you route requests from the Core site back to the Web Forms site? Where it's on a different port number would it require a corresponding rewrite section in it's config?

2) Can this setup be achieved on developers machines using Visual Studio and IIS Express without the need for a publish of the Core site?

Thanks,
Gavin
Gravatar # re: Integrating ASP.NET Core With Webforms Using IIS URL Rewrite
by Steve at 4/10/2017 11:36 AM

Hey Gavin!

1) If the core website writes URLs in its output to port 80 (or writes relative URLs with no specified port), they'll automatically point back to the webforms site - the URL rewrite happens transparently, so as far as the browser knows the core content comes from port 80.

2) If the rewrite rules point to the IIS Express port and the site is running, I think it will work, yes. I haven't tried it, but I see no reason why it wouldn't be ok :)

Cheers,
Steve
Gravatar # re: Integrating ASP.NET Core With Webforms Using IIS URL Rewrite
by Artyom at 5/3/2017 3:49 PM

Do POST requests work for you with this approach? I have GET requests working like a charm while POSTs are just time out...
Gravatar # re: Integrating ASP.NET Core With Webforms Using IIS URL Rewrite
by Steve at 5/3/2017 8:01 PM

I haven't had to support any post actions just yet, but this page looks to give a solution to matching post requests:

https://forums.iis.net/p/1168257/1995258.aspx
Gravatar # re: Integrating ASP.NET Core With Webforms Using IIS URL Rewrite
by Artyom at 5/5/2017 8:02 AM

Thanks for reply. Well, it's turned out the issue is quite known and not related to asp.net core, but rather to rewriting peer... it looks like no acceptable and working solution found yet, e.g.:

https://forums.iis.net/t/1187225.aspx?ARR+POST+requests+causing+502+3+timeouts

http://stackoverflow.com/questions/5475608/iis7-application-request-routing-arr-reverse-proxy-combined-with-managed-modul

Post A Comment
Title:
Name:
Email:
Comment:
Verification: