【问题标题】:ASP MVC \ Subdomains on LocalhostASP MVC \ 本地主机上的子域
【发布时间】:2016-05-10 15:10:47
【问题描述】:

我正在本地使用 IIS Express 测试 ASP MVC EF 应用程序。我正在尝试确定 HTTP 请求中的子域,但收到“错误请求 - 无效主机名”错误

我查看了一些有关更改主机文件的答案,但没有解决错误。

在我的 HomeController 中,我有这个方法可以简单地打印请求的 URL

public string Index() { var hn = Request.Headers["HOST"];返回 hn.ToString(); }

查看本地主机时 -> 页面加载

查看tenant1.localhost时->错误请求

如果有人能指出正确的方向来解决此错误,将不胜感激。

谢谢!

【问题讨论】:

  • 无效的主机名是一个“dns”问题 - 这就是为什么您需要在 hosts 文件中为您想要解决的任何/所有“本地”“子域”创建条目。假设您在 hosts 文件中有一个 tenant1.localhost 条目以使其正常工作(还假设在您完成 hosts 文件后正确设置了 IIS - 可能通过主机头设置)。您需要在 IIS 管理器中执行此操作。
  • 嘿,是的,我这样做了:127.0.0.1 localhost 127.0.0.1 tenant1.localhost

标签: asp.net asp.net-mvc-4


【解决方案1】:

默认情况下,IIS Express 只允许localhost。为了允许另一个域在开发中访问您的站点,您必须在 %USERPROFILE%\Documents\IISExpress\config\applicationhost.config 中手动添加绑定。找到与您的应用程序对应的<site> 节点,并在<bindings> 节点中添加一个新的<binding>。那里将有默认绑定用作指南。不过,不要乱用默认绑定,否则可能会在 Visual Studio 中出现奇怪的错误。

此外,我建议使用localtest.me 之类的东西来测试子域,因为subdomain.localhost 构造往往不能很好地工作,因为大多数事情都会尝试假设localhost 是顶级域名。基本上,localtest.me 是一个已设置为通配符将所有内容路由到 127.0.0.1 (localhost) 的域。因此,您可以选择和使用您想要的任何子域。值得一提的是,这对于测试开发中的 Facebook 等第三方集成也非常有效,因为它们不允许使用 localhost。

【讨论】:

  • 你好克里斯,我在站点下的 applicationhost.config 中找不到任何内容。你的意思是在我的 .vs 文件夹中的那个吗?也许新约定将设置存储在 .vs 文件夹中。我读了另一个答案。
【解决方案2】:

我试过Paul Taylor 上面的答案非常好,但这对我来说并不完全有效。 我使用Route 类的这个实现。

将您的自定义域添加到 C:/Windows/System32/drivers/etc/hosts 文件中

  • 127.0.0.1 subdomain.localhost.com

DomainData.cs

public class DomainData
{
  public string Protocol { get; set; }
  public string HostName { get; set; }
  public string Fragment { get; set; }
}

DomainRoute.cs

public class DomainRoute : Route
{
  private Regex domainRegex;
  private Regex pathRegex;

  public string Domain { get; set; }

  public DomainRoute(string domain, string url, RouteValueDictionary defaults)
    : base(url, defaults, new MvcRouteHandler())
{
    Domain = domain;
}

public DomainRoute(string domain, string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
    : base(url, defaults, routeHandler)
{
    Domain = domain;
}

public DomainRoute(string domain, string url, object defaults)
    : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
{
    Domain = domain;
}

public DomainRoute(string domain, string url, object defaults, IRouteHandler routeHandler)
    : base(url, new RouteValueDictionary(defaults), routeHandler)
{
    Domain = domain;
}

public override RouteData GetRouteData(HttpContextBase httpContext)
{
    // Build regex
    domainRegex = CreateRegex(Domain);
    pathRegex = CreateRegex(Url);

    // Request information
    string requestDomain = httpContext.Request.Headers["host"];
    if (!string.IsNullOrEmpty(requestDomain))
    {
        if (requestDomain.IndexOf(":") > 0)
        {
            requestDomain = requestDomain.Substring(0, requestDomain.IndexOf(":"));
        }
    }
    else
    {
        requestDomain = httpContext.Request.Url.Host;
    }
    string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) +
                         httpContext.Request.PathInfo;

    // Match domain and route
    Match domainMatch = domainRegex.Match(requestDomain);
    Match pathMatch = pathRegex.Match(requestPath);

    // Route data
    RouteData data = null;
    if (domainMatch.Success && pathMatch.Success && requestDomain.ToLower() != "tg.local" &&
        requestDomain.ToLower() != "tg.terrasynq.net" && requestDomain.ToLower() != "www.townsgossip.com" &&
        requestDomain.ToLower() != "townsgossip.com")
    {
        data = new RouteData(this, RouteHandler);

        // Add defaults first
        if (Defaults != null)
        {
            foreach (KeyValuePair<string, object> item in Defaults)
            {
                data.Values[item.Key] = item.Value;
            }
        }

        // Iterate matching domain groups
        for (int i = 1; i < domainMatch.Groups.Count; i++)
        {
            Group group = domainMatch.Groups[i];
            if (group.Success)
            {
                string key = domainRegex.GroupNameFromNumber(i);

                if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
                {
                    if (!string.IsNullOrEmpty(group.Value))
                    {
                        data.Values[key] = group.Value;
                    }
                }
            }
        }

        // Iterate matching path groups
        for (int i = 1; i < pathMatch.Groups.Count; i++)
        {
            Group group = pathMatch.Groups[i];
            if (group.Success)
            {
                string key = pathRegex.GroupNameFromNumber(i);

                if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
                {
                    if (!string.IsNullOrEmpty(group.Value))
                    {
                        data.Values[key] = group.Value;
                    }
                }
            }
        }
    }

    return data;
}

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
    return base.GetVirtualPath(requestContext, RemoveDomainTokens(values));
}

public DomainData GetDomainData(RequestContext requestContext, RouteValueDictionary values)
{
    // Build hostname
    string hostname = Domain;
    foreach (KeyValuePair<string, object> pair in values)
    {
        hostname = hostname.Replace("{" + pair.Key + "}", pair.Value.ToString());
    }

    // Return domain data
    return new DomainData
    {
        Protocol = "http",
        HostName = hostname,
        Fragment = ""
    };
}

private Regex CreateRegex(string source)
{
    // Perform replacements
    source = source.Replace("/", @"\/?");
    source = source.Replace(".", @"\.?");
    source = source.Replace("-", @"\-?");
    source = source.Replace("{", @"(?<");
    source = source.Replace("}", @">([a-zA-Z0-9_\-]*))");

    return new Regex("^" + source + "$");
}

private RouteValueDictionary RemoveDomainTokens(RouteValueDictionary values)
{
    var tokenRegex =
        new Regex(
            @"({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?");
    Match tokenMatch = tokenRegex.Match(Domain);
    for (int i = 0; i < tokenMatch.Groups.Count; i++)
    {
        Group group = tokenMatch.Groups[i];
        if (group.Success)
        {
            string key = group.Value.Replace("{", "").Replace("}", "");
            if (values.ContainsKey(key))
                values.Remove(key);
        }
    }

    return values;
  }
}

参考:Domain Routing in MVC5

【讨论】:

    猜你喜欢
    • 2011-11-12
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多