Pregunta

This is not regarding version control for the source. This is a requirement of the business and how it interfaces with various vendors, so I'm trying to work out the best possible way to set this up. Essentially we need to serve a different major version of a site out depending on who is hitting it - and not display that version in the URL. Here's how it works right now:

The site is ASP.NET MVC 4 running on IIS 7. Right now it's set up with a default site in IIS with applications underneath. Each application is a version of the site. When the initial request hits the site it runs through a custom ISAPI filter. That filter grabs what is essentially a user ID variable from the URL and uses it to query a SQL database. This database links the user ID to the version that needs to be served (the application in IIS), and appends it to the beginning of the URL. So http://site.com/1 becomes http://site.com/2.1.0.0/1, thus pointing to the correct directory in IIS. Then within the site, custom HtmlHelpers are used to strip the version from the URL string when anchor links or buttons etc. are created. When user clicks one of those links, it repeats.

This seems unnecessarily complicated. I'd like to not use custom HtmlHelpers and just silently redirect the requests to a different virtual directory/physical path in IIS somehow.

For alternatives, we've looked at:

  • Using the URL Rewrite in IIS - but this requires the version to come in on the initial request, and the end user isn't going to know that.
  • Using a custom HttpHandler - but that requires that a website be hit already - the request already well into IIS. It could be that I don't quite know enough to make it work.
  • Attempting to not rewrite the URL but just the virtual directory/physical path with the ISAPI filter, but there doesn't seem to be any hook we can use to do so.
  • Create a custom HttpModule that calls HttpContext.RewritePath() but ran into issues with MVC routes and the HtmlHelpers, just as if there was no HttpModule doing anything.

I don't have code to share, really - it's proprietary. What I'm looking for is more theory. How would such a crazy website versioning contraption be set up?

¿Fue útil?

Solución

After a lot more playing, we found the answer. The issue with Garath's comments above is that, while outbound rules can rewrite Html.ActionLink and Html.BeginForm, they cannot do anything for RedirectToRoute or RedirectToAction and more. Outbound rules only parse the generated HTML content and change it before sending it back to the browser. Outbound rules are also incompatible with gzip, which is understandable but annoying.

In short, we created a custom rewrite provider that uses the SQL connection to pull the version and return the correct URL. We also hooked into the IIS URL Rewrite capability to send custom server variables to prevent querying the database more than once per session. It works like this:

  1. Request hits the IIS URL Rewrite module
  2. First rule checks for a cookie value and, if it exists, rewrites the URL based on that and stops processing further rules.
  3. If the cookie isn't there, it calls the custom provider, which uses SQL to rewrite the URL.
  4. The second rule also sets a custom server variable passed in the header to the version.
  5. The website checks for that header variable, and if set, creates a cookie with the version.
  6. Rinse and repeat.

Links that helped us out:

Hopefully this can help someone else out in the future.

Side note - the custom rewrite provider must target .NET 2.0, which is left out of the first link above.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top