如果我没记错的话,您基本上是在寻找一个钩子,您可以在其中检查由 web api 的属性路由探测机制生成的结束路由前缀或路由模板,并在它们被添加到路由表之前对其进行修改。通过这种方式,您可以插入具有属性控制器的第 3 方模块并修改其路由模板,以防止它们与其他模块或您自己的应用程序的路由混淆……对吗?
Web API 提供 IRoutePrefix 和 RoutePrefixAttribute (实现 IRoutePrefix)等类型,以支持创建自定义 RoutePrefixes,您可以在其中更改路由前缀。但从您正在寻找的场景来看,我认为这没有多大帮助。
不幸的是,我无法推荐 Web API 中的好方法来执行此操作。这种场景在设计时就出现了,但由于时间限制,我们无法提供必要的钩子。
更新:
根据您的评论,以下是我创建自定义路由属性并修改模板的示例,方法是在将模块名称添加到路由模板之前将其添加到路由表。
正如我在评论中提到的,如果您拥有所有模块,则可以使用此方法,因为您可以使用此自定义路由属性。如果您期望 3rd 方模块,那么您必须与他们达成协议,以便他们也使用相同的属性。但这很容易出错,例如在他们不使用此自定义属性而是使用默认 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();
}
}