I have an ASP.NET MVC application that's used by different companies. The URL for the app looks something like this: http://myapp.com/companyA/stuff
or http://myapp.com/companyB/stuff
. I get the company identifier from the URL in Application_BeginRequest
and then do a RewritePath
to http://myapp.com/stuff
.
My question is about relative links that ASP.NET MVC generates. It appears that these links are generated to the root of the site, disregarding company identifiers in the URL. For example, once at http://myapp.com/companyA/stuff
, @Url.Action("index", "home")
creates a link that points to http://myapp.com/ not http://myapp.com/companyA/
Is there a way to instruct ASP.NET MVC to use a certain baseURL
when generating relative links?
Thanks.
The problem is that you are using URL rewriting. URL rewriting is a one-way map - URL to resource.
The modern (and more MVC-centric) way of doing things is to use .NET routing. Routing is a 2-way map from URL to resource and from resource back to URL. A resource is identified by a (preferably unique) set of route values.
Routing in MVC is very flexible. The MapRoute
extension method can be used to create quite a range of options. However, you can literally create any URL scheme you want by inheriting either the Route
class or RouteBase
class. You can literally use anything in the request (URL, headers, cookies, session state, etc) to route to a resource (usually a controller action). See this answer for an advanced example.
But in your case, you can simply set up a route to map to the correct company.
routes.MapRoute(
name: "Company",
url: "{company}/{action}",
defaults: new { controller = "Company", action = "Index" },
constraints: new { company = @"companyA|companyB" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Then you just need a company route (a controller for each company is another option, it depends on how much you want to share).
public class CompanyController : Controller
{
// CompanyA/
// CompanyA/Index
// CompanyB/
// CompanyB/Index
public ActionResult Index()
{
return View();
}
// CompanyA/Stuff
// CompanyB/Stuff
public ActionResult Stuff()
{
return View();
}
}
Then in your application, you need to specify the company when building the ActionLinks
, which will use the routing framework to build the URL.
@Url.ActionLink("Home", "Index", "Home", new { company = "companyA" }, null)
@Url.ActionLink("Home", "Index", "Home", new { company = "companyB" }, null)
An alternative option that might be better for this scenario is to use Areas to separate each company. Also see the MSDN tutorial. Areas each have their own route and they act like different containers within an MVC application.
But either way, you should really get rid of the URL rewriting because that is an antiquated way of working with URLs.