The root prefix for attribute routing WebApi v2

I am currently working on extensible WebApi, where individual dynamically loadable modules can register their own routes. My initial version was built using ASP.NET WebApi v1, using a technique based on https://github.com/darrelmiller/ApiRouter , however I would like to use attribute-based routing available with ASP.NET WebApi v2

So to speak, I have a module with the following controller

[RoutePrefix("foo")]
public class FooController : ApiController {

    [Route("{id}")]
    public object GetFoo(int id) {
        return id;
    }
}

If I just call config.MapHttpAttributeRoutes(), then this controller will be tied to http://localhost/foo/2. What I would like to do is programmatically change the route prefix for the controllers. Therefore, he should hope to be connected with something likehttp://localhost/modules/FooModule/foo/2

Is there a way to do this with the provided tools, or will I have to continue using my original method?

+4
source share
1 answer

If I'm not mistaken, you are basically looking for a hook where you can examine the final route prefix or route pattern generated by the web api attribute routing probing mechanism and modify them before they are added to the route table. Thus, you can connect third-party modules with attribute controllers and modify their route patterns so that they cannot interact with other modules or your own application routes ... is this correct?

Web API , IRoutePrefix RoutePrefixAttribute ( IRoutePrefix), RoutePrefixes, . , , , .

, Web API . , - .

:
. , , , . , , . , , , RouteAttribute...

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public class MyRouteAttribute : Attribute, IDirectRouteFactory
{
    private readonly string _template;

    public MyRouteAttribute(string template)
    {
        _template = template;
    }

    public string Template
    {
        get { return _template; }
    }

    public string Name { get; set; }

    public int Order { get; set; }

    public virtual IDictionary<string, object> Defaults
    {
        get { return null; }
    }

    public virtual IDictionary<string, object> Constraints
    {
        get { return null; }
    }

    public virtual IDictionary<string, object> DataTokens
    {
        get { return null; }
    }

    public RouteEntry CreateRoute(DirectRouteFactoryContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        IDirectRouteBuilder builder = context.CreateBuilder(Template);

        //You would receive the final template..that is RoutePrefix + the route template
        string finalTemplate = builder.Template;

        //Modify this template to have your ModuleName
        builder.Template = "modulename/" + finalTemplate;

        builder.Name = Name;
        builder.Order = Order;

        IDictionary<string, object> builderDefaults = builder.Defaults;

        if (builderDefaults == null)
        {
            builder.Defaults = Defaults;
        }
        else
        {
            IDictionary<string, object> defaults = Defaults;

            if (defaults != null)
            {
                foreach (KeyValuePair<string, object> defaultItem in defaults)
                {
                    builderDefaults[defaultItem.Key] = defaultItem.Value;
                }
            }
        }

        IDictionary<string, object> builderConstraints = builder.Constraints;

        if (builderConstraints == null)
        {
            builder.Constraints = Constraints;
        }
        else
        {
            IDictionary<string, object> constraints = Constraints;

            if (constraints != null)
            {
                foreach (KeyValuePair<string, object> constraint in constraints)
                {
                    builderConstraints[constraint.Key] = constraint.Value;
                }
            }
        }

        IDictionary<string, object> builderDataTokens = builder.DataTokens;

        if (builderDataTokens == null)
        {
            builder.DataTokens = DataTokens;
        }
        else
        {
            IDictionary<string, object> dataTokens = DataTokens;

            if (dataTokens != null)
            {
                foreach (KeyValuePair<string, object> dataToken in dataTokens)
                {
                    builderDataTokens[dataToken.Key] = dataToken.Value;
                }
            }
        }

        return builder.Build();
    }
}
+2

Source: https://habr.com/ru/post/1526977/


All Articles