0

I have an ASP.NET MVC app with the following deployment requirements:

The URL structure must be something like:

http://server/app/[enterprise]/[communinty]/{controller}/{action}/...

What I think I want to be able to do is intercept the URL before the MVC route handler gets its hands on it, remove the [enterprise]/[community] parts, and then allow MVC to continue processing as if the original URL had not contained those two segments.

Here's why:

The application exposes multiple portals to multiple customers (enterprises), and each community within an enterprise has its own user population. This kind of scheme could also be served by physically deploying one application instance (binaries,content,web.config) into each [community] directory, but for logistical and performance reasons, I don't think we want to go down this path. So I'm trying to virtualize it through routing tricks.

Any suggestions on how to go about this scheme, or alternate solutions would be appreciated.

We are on IIS 7, if that makes any difference.

jlew
  • 10,491
  • 1
  • 35
  • 58
  • So people visit `http://server/app/MyCompany/FightingDogs/Home/Index` and then you want to extract MyCompany/FightingDogs so that the URL now reads `http://server/app/Home/Index`? (I suppose you store the reference to MyCompany/Fightingdocs in a session or cookie?) – jao Jul 23 '10 at 20:43
  • Not exactly. I want the browser-visible URL to remain http://server/app/MyCompany/FightingDogs/Home/Index, but I don't want the MVC controllers/models/etc to have to know about the "MyCompany/FightingDogs" part. – jlew Jul 23 '10 at 20:49
  • Would it make more sense to not use routing, but rather store the current user's Enterprise and Community in the Session when they log in? I can imagine it would be difficult to include URLs in documentation if they are unique to each group of users. – Ryan Jul 24 '10 at 04:07
  • @Ryan - We have no (server-side) session state in the application, and I don't want to add it for this. Documentation is not an issue. I have been toying with the idea of adding this information as claims to the security token cookike. – jlew Jul 26 '10 at 13:50

2 Answers2

1

You can use the following route before the default route

routes.MapRoute(
    null,
    "{enterprise}/{community}/{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

You can then ignore {enterprise} and {community} parameters in your action methods.

Caline
  • 175
  • 1
  • 1
  • 7
  • You know, I had thought that it would be impossible to "ignore" these elements (that the view models would need to include them), but it appears you're right. Thanks! – jlew Jul 27 '10 at 13:41
0

Here is a possible solution with IIS Rewrite module. It may not be the best approach, but it may work. Is there an easier/better option within the MVC routing? Not sure. Only just started doing that myself.

Using "http://server.com/app/enterprise/community/controller/action/" as an example.

What happens:

  1. Strips the string out of the URL. New URL: http://server.com/controller/action/
  2. Redirects the user to new URL. User's browser now shows: http://server.com/controller/action/
  3. Takes the new URL and tries to rebuild it to grab the correct content. User's browser shows: http://server.com/controller/action/ ; IIS returns: http://server.com/app/enterprise/community/controller/action/

All of this would be in the web.config once the IIS rewrite module is installed:

<rewrite>
    <rules>
        <clear />

        <rule name="Redirect to remove Offending String" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
            <match url="server.com/app/enterprise/community*" />
            <action type="Redirect" url="/{R:1}" />
            <conditions logicalGrouping="MatchAll">
                <add input="{SERVER_NAME}" pattern="*server.com*" />
            </conditions>
        </rule>

        <rule name="Rewrite to get Original Content" enabled="true" patternSyntax="Wildcard" stopProcessing="false">
            <match url="*" />
            <conditions logicalGrouping="MatchAll">
                <add input="{SERVER_NAME}" pattern="*server.com*" />
            </conditions>
            <action type="Rewrite" url="app/enterprise/community{R:1}" />
        </rule>

    </rules>
</rewrite>

Note: Just did this quick, haven't tested.

mcnarya
  • 841
  • 2
  • 11
  • 19
  • He's using mvc, which has routing built in (in case you didn't know) – jao Jul 23 '10 at 20:44
  • I realize the MVC has routing built into it, but from what I thought jlew wanted I read it and thought the MVC routing might not be able to do it. However, after reading jlew's new comments my approach won't work for what he wants, which does deal directly with the MVC routing. – mcnarya Jul 23 '10 at 21:06