我们已经编写了大量代码,其中使用以下代码编写URL:
Url.Action("Index", "MyController", new {page=1})
我们的应用程序是一个多租户应用程序,我们的用户登录到他们的数据库。这意味着登录过程允许用户选择他们想要用于会话的数据库。我们没有在开头构建它,因此数据库名称是URL的一部分。这只是会议的一部分。
现在我们希望将数据库名称放在所有URL中,这样用户仍然可以使用浏览器URL创建书签,并正确访问该特定页面,而无需在登录期间选择正确的匹配数据库。从本质上讲,如果在ASP.NET MVC中有一种方法可以进行上述调用,那就太好了:
Url.Action("Index", "MyController", new {page=1, clientName=Identity.ClientName})
无需去任何地方并且手动进行。我们正在谈几千个地方......
这可行吗?
答案 0 :(得分:0)
好吧,我认为现在无法做到这一点,我们需要编写自己的Url.Action,Html.ActionLink和Controller.Redirect实现,只需进行全局搜索和替换即可使用我们的版本。太糟糕了。
答案 1 :(得分:0)
我今天必须解决一个非常类似的问题。当我在寻找解决方案时,我找到了你的问题。我现在已经找到了一个解决方案,虽然它可能与您的项目不再相关,但对于偶然发现它的人来说可能会有所帮助。
我们可以通过向您的路由集合而不是vanilla MVC Route类添加Route
类的自定义实现来解决此问题。所以像这样:
public class ClientNameRoute : Route
{
public ClientNameRoute(string url, IRouteHandler routeHandler) : base (url, routeHandler) {}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
values["clientName"] = Identity.ClientName;
return base.GetVirtualPath(requestContext, values);
}
}
然后,您需要制作一些扩展方法,以便更轻松地注册这些路由。例如:
public static RegionRoute MapClientNameRoute(this AreaRegistrationContext context, string name, string url, object defaults)
{
if (context.Routes == null)
throw new ArgumentNullException("context.Routes");
if (url == null)
throw new ArgumentNullException("url");
if (context.Namespaces != null)
context.Namespaces.ToArray();
var route = new ClientNameRoute(url, new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(defaults),
DataTokens = new RouteValueDictionary(),
};
route.DataTokens["area"] = context.AreaName;
var useNamespaceFallback = context.Namespaces == null || context.Namespaces.Count == 0;
route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;
if (!useNamespaceFallback)
route.DataTokens["Namespaces"] = context.Namespaces.ToArray();
context.Routes.Add(name, route);
return route;
}
public static RegionRoute MapClientNameRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces)
{
if (routes == null)
throw new ArgumentNullException("routes");
if (url == null)
throw new ArgumentNullException("url");
var route = new ClientNameRoute(url, new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(defaults),
DataTokens = new RouteValueDictionary()
};
if (namespaces != null && namespaces.Length > 0)
{
route.DataTokens["Namespaces"] = namespaces;
}
routes.Add(name, route);
return route;
}