Click here to Skip to main content
15,890,947 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
For some reason,I want to create webapi route template like this:
C#
HttpConfiguration.Routes.Add("DomainDefaultApi", new DomainHttpRoute("{controller}.12345.com", "api/{id}", new System.Web.Http.Routing.HttpRouteValueDictionary(new { id = RouteParameter.Optional })));

I create the DomainHttpRoute class:
C#
public class DomainHttpRoute : HttpRoute
{
    public string Domain { get; set; }

    public DomainHttpRoute(string domain) : this(domain, null, null, null, null, null) { }

    public DomainHttpRoute(string domain, string routeTemplate) : this(domain, routeTemplate, null, null, null, null) { }

    public DomainHttpRoute(string domain, string routeTemplate, HttpRouteValueDictionary defaults) : this(domain, routeTemplate, defaults, null, null, null) { }

    public DomainHttpRoute(string domain, string routeTemplate, HttpRouteValueDictionary defaults, HttpRouteValueDictionary constraints) : this(domain, routeTemplate, defaults, constraints, null, null) { }

    public DomainHttpRoute(string domain, string routeTemplate, HttpRouteValueDictionary defaults, HttpRouteValueDictionary constraints, HttpRouteValueDictionary dataTokens) : this(domain, routeTemplate, defaults, constraints, dataTokens, null) { }

    public DomainHttpRoute(string domain, string routeTemplate, HttpRouteValueDictionary defaults, HttpRouteValueDictionary constraints, HttpRouteValueDictionary dataTokens, HttpMessageHandler handler)
        : base(routeTemplate, defaults, constraints, dataTokens, new DomainHttpMessageHandler())
    {
        Domain = domain;
    }

    public override IHttpRouteData GetRouteData(string virtualPathRoot, HttpRequestMessage request)
    {
        _DomainRegex = _CreateRegex(this.Domain);
        string requestDomain = request.Headers.Host;
        if (string.IsNullOrEmpty(requestDomain))
            requestDomain = request.RequestUri.Host;
        else if (requestDomain.IndexOf(":") > 0)
            requestDomain = requestDomain.Substring(0, requestDomain.IndexOf(":"));
        Match domainMatch = _DomainRegex.Match(requestDomain);
        IHttpRouteData data = null;
        if (domainMatch.Success)
        {
            data = base.GetRouteData(virtualPathRoot, request);
            if (data != null)
            {
                for (int i = 0; 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) && !string.IsNullOrEmpty(group.Value))
                            data.Values[key] = group.Value;
                    }
                }
            }
        }
        return data;
    }

    public override IHttpVirtualPathData GetVirtualPath(HttpRequestMessage request, IDictionary<string, object> values)
    {
        return base.GetVirtualPath(request, _RemoveDomainTokens(values));
    }

    protected override bool ProcessConstraint(HttpRequestMessage request, object constraint, string parameterName, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
    {
        object obj2;
        IHttpRouteConstraint constraint2 = constraint as IHttpRouteConstraint;
        if (constraint2 != null)
            return constraint2.Match(request, this, parameterName, values, routeDirection);
        string str = constraint as string;
        if (str == null)
            throw new InvalidOperationException("ProcessConstraint");
        values.TryGetValue(parameterName, out obj2);
        string input = Convert.ToString(obj2, CultureInfo.InvariantCulture);
        string pattern = "^(" + str + ")$";
        return Regex.IsMatch(input, pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
    }

    private Regex _DomainRegex;
    private Regex _PathRegex;

    private Regex _CreateRegex(string source)
    {
        source = source.Replace("/", @"\/?");
        source = source.Replace(".", @"\.?");
        source = source.Replace("-", @"\-?");
        source = source.Replace("{", @"(?<");
        source = source.Replace("}", @">(\w*))");
        return new Regex("^" + source + "$");
    }

    private IDictionary<string, object> _RemoveDomainTokens(IDictionary<string, object> values)
    {
        Regex tokenRegex = new Regex(@"({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?({\w*})*-?\.?\/?");
        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("{", string.Empty).Replace("}", string.Empty);
                if (values.ContainsKey(key))
                    values.Remove(key);
            }
        }
        return values;
    }

}

there is no error,but it cannot works,find no controllerName.
Who can help me?
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900