以下の例では、ユーザーが独自に設定できるサブドメインをASP.NET MVCで実現するためのカスタムルーティングクラスを作成します。
これで、ユーザーが独自に設定したサブドメインに対応する機能を実装できます。
まず、カスタムルーティングクラスを作成します。
public class CustomSubdomainRoute : Route
{
private Regex subdomainRegex;
private Regex urlRegex;
public string SubdomainPattern { get; set; }
public CustomSubdomainRoute(string subdomainPattern, string urlPattern, RouteValueDictionary defaults)
: base(urlPattern, defaults, new MvcRouteHandler())
{
SubdomainPattern = subdomainPattern;
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
subdomainRegex = CreateRegex(SubdomainPattern);
urlRegex = CreateRegex(Url);
string requestHost = httpContext.Request.Headers["host"];
if (string.IsNullOrEmpty(requestHost))
{
requestHost = httpContext.Request.Url.Host;
}
else if (requestHost.Contains(":"))
{
requestHost = requestHost.Split(':')[0];
}
string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
Match hostMatch = subdomainRegex.Match(requestHost);
Match pathMatch = urlRegex.Match(requestPath);
if (hostMatch.Success && pathMatch.Success)
{
var routeData = new RouteData(this, RouteHandler);
if (Defaults != null)
{
foreach (var item in Defaults)
{
routeData.Values[item.Key] = item.Value;
}
}
for (int i = 1; i < hostMatch.Groups.Count; i++)
{
Group group = hostMatch.Groups[i];
if (group.Success)
{
string key = subdomainRegex.GroupNameFromNumber(i);
if (!string.IsNullOrEmpty(key) && !char.IsDigit(key[0]))
{
routeData.Values[key] = group.Value;
}
}
}
for (int i = 1; i < pathMatch.Groups.Count; i++)
{
Group group = pathMatch.Groups[i];
if (group.Success)
{
string key = urlRegex.GroupNameFromNumber(i);
if (!string.IsNullOrEmpty(key) && !char.IsDigit(key[0]))
{
routeData.Values[key] = group.Value;
}
}
}
return routeData;
}
return null;
}
private Regex CreateRegex(string pattern)
{
pattern = pattern.Replace("/", @"\/?");
pattern = pattern.Replace(".", @"\.");
pattern = pattern.Replace("-", @"\-?");
pattern = pattern.Replace("{", @"(?<");
pattern = pattern.Replace("}", @">([a-zA-Z0-9_]*))");
return new Regex("^" + pattern + "$");
}
}
次に、サブドメイン情報を持つデータモデルを作成します。
public class SubdomainInfo
{
public string Protocol { get; set; } = "http";
public string Host { get; set; }
public string Fragment { get; set; } = "";
}
Global.asaxでルートを登録します。
routes.Add("CustomSubdomainRoute", new CustomSubdomainRoute(
"{subdomain}.example.com", // サブドメインパターン
"{controller}/{action}/{id}", // URLパターン
new { subdomain = "", controller = "Home", action = "Index", id = "" } // デフォルト値
));
最後に、HomeControllerでサブドメイン情報を取得します。
public ActionResult Index()
{
string subdomain = RouteData.Values["subdomain"]?.ToString();
// 必要な処理をここに追加
return View();
}