gpt4 book ai didi

asp.net-mvc - 通配符子域路由 ASP MVC

转载 作者:行者123 更新时间:2023-12-01 11:43:25 27 4
gpt4 key购买 nike

我正在寻找一种将通配符子域路由到 ASP MVC 4 中的 Controller 的方法。

所以像这样:

CompanyName.mydomain.com

需要翻译成这样:

mydomain.com/CompanyName

我找不到有关如何执行此操作的任何信息,我被困住了。这是 IIS 还是 ASP MVC 路由?

最佳答案

所以过了一段时间,我自己在应用层面解决了这个问题。IIS 重写没有工作,ASP MVC 没有匹配正确的路由,它会 404 输出。

最终对我有用的解决方案是自己实现路由类,该类在主机名中搜索参数并将其映射为路由参数。它现在可以完美运行,自定义实现也很简单。我爱上了 ASP MVC 在此过程中为您提供的灵 active :)

因此自定义路由需要两个重写,一个用于匹配传入路由的方法“GetRouteData”,另一个用于写入传出路由的“GetVirtualPath”。

这是整个自定义路由类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace System.Web.Routing
{
public class WildcardRoute : Route
{


public WildcardRoute(string url, IRouteHandler handler)
: base(url, handler)
{

}
public WildcardRoute(string url, RouteValueDictionary defaults, IRouteHandler handler)
: base(url, defaults, handler)
{
}

public WildcardRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler handler)
: base(url, defaults, constraints, handler)
{
}

public WildcardRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler handler)
: base(url, defaults, constraints, dataTokens, handler)
{

}


public override RouteData GetRouteData(HttpContextBase httpContext)
{
// save the original path before we edit it
var orignalPath = HttpContext.Current.Request.Path;

//split the hostname
var split = HttpContext.Current.Request.Url.Host.Split('.');
// fire only if there is more than 2 items in the split (company.mydomain.com) and if the first one is not www
if (split.Count() > 2 && split[0].ToLower() != "www")
{
var split2 = HttpContext.Current.Request.Path.Split('/'); // split everything after the hostname into segments
string newPath = "/" + split[0]; // take the company from company.mydomain.com and rewrite it to mydomain.com/company
foreach (var item in split2) // add all the other segments that come after mydomain.com/company
{ // end result might be for example - mydomain.com/company/Home/Index
newPath = newPath + "/" + item;
}
httpContext.RewritePath(newPath); // rewrite the path into the newone
}

RouteData data = base.GetRouteData(httpContext); // match the route with the new path
if (data == null) // if there is no match in this route write the path back to the original one
{
httpContext.RewritePath(orignalPath);
}
return data;
}

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{

var data = base.GetVirtualPath(requestContext, values); // do the original url write
var split = requestContext.HttpContext.Request.Url.Host.Split('.'); // split the host by '.'

var item = requestContext.RouteData.Values.FirstOrDefault(x => x.Key == "PermalinkTitle"); // the PermalinkTitle is the name of the "company" route value in mydomain.com/company in my implementation
if (split.Count() > 0 && split[0].ToLower().Contains(item.Value.ToString().ToLower())) // fire only if the hostname contains the "company" route value
{
data.VirtualPath = data.VirtualPath.Replace(item.Value.ToString(), "");
if (data.VirtualPath.StartsWith("/"))
data.VirtualPath = data.VirtualPath.Substring(1);
// this code removes the company part from the path so we dont get company.mydomain.com/company/controller/action rather we just get company.mydomain.com/controller/action
}
return data;
}

}
}

此实现非常灵活,可以与所有这些路由一起使用 - “company.mydomain.com”、“mydomain.com/company”和“www.mydomain.com/company”。

创建自定义路由类后,您需要使用映射自定义类型路由的 Map 方法扩展 RouteCollection,如果您使用区域,则还需要扩展 AreaRegistrationContext,因为区域路由映射会通过它。这是整个实现:

using System;
using System.Web.Mvc;
using System.Web.Routing;

namespace System.Web.Routing
{
public static class WildcardRoutesExtension
{

public static WildcardRoute MapWildcardRoute(this RouteCollection routes, string name, string url, object defaults)
{

WildcardRoute route = new WildcardRoute(
url,
new RouteValueDictionary(defaults),
new MvcRouteHandler());
routes.Add(name, route);

return route;
}

public static WildcardRoute MapWildcardRoute(this AreaRegistrationContext context, string name, string url, object defaults)
{
WildcardRoute route = new WildcardRoute(
url,
new RouteValueDictionary(defaults),
new RouteValueDictionary(new {}),
new RouteValueDictionary(new {Area = context.AreaName }),
new MvcRouteHandler());

context.Routes.Add(name, route);
return route;
}


public static WildcardRoute MapWildcardRoute(this AreaRegistrationContext context, string name, string url, object defaults, object constraints)
{
WildcardRoute route = new WildcardRoute(
url,
new RouteValueDictionary(defaults),
new RouteValueDictionary(constraints),
new RouteValueDictionary(new {Area = context.AreaName }),
new MvcRouteHandler());

context.Routes.Add(name, route);
return route;
}

public static WildcardRoute MapWildcardRoute(this RouteCollection routes, string name, string url, object defaults, object constraints)
{
WildcardRoute route = new WildcardRoute(
url,
new RouteValueDictionary(defaults),
new RouteValueDictionary(constraints),

new MvcRouteHandler());
routes.Add(name, route);
return route;
}
}
}

当你拥有所有这些后,你现在只需要像这样为 RouteConfig 类中的常规路由映射你的自定义路由:

    public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{


// rest of your routes

routes.MapWildcardRoute(
name: "Default",
url: "{PermalinkTitle}/{controller}/{action}",
defaults: new { }
);

//Rest of your routes
}

或者像这样用于 Areas AreaRegistration 类中的区域:

    public override void RegisterArea(AreaRegistrationContext context)
{

context.MapWildcardRoute(
"MyArea_default",
"{PermalinkTitle}/MyArea/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);

}

关于asp.net-mvc - 通配符子域路由 ASP MVC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17392480/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com