мне удалось сделать то, что я хотите с помощью атрибута RoutePrefix на контроллере с дополнительным MapRoute с привязкой к нему.
Вот код, если кто-то пытается сделать что-то подобное
Сначала добавьте routePrefix к контроллеру, который вы хотите позвонить
[RoutePrefix("api/{myCustomName}")]
public MyController : ApiController {
}
Теперь в моем файле WebApiConfig, мне необходимо добавьте следующие строки
// Web API routes
config.MapHttpAttributeRoutes();
// handle calling MyController using custom name
config.Routes.MapHttpRoute(
name: "ModuleDataApi",
routeTemplate: "api/{myCustomName}/{id}",
defaults: new { controller = "MyController" },
constraints: new { moduleType = new MyCustomRouteConstraint() }
);
Теперь создайте ограничение, которое проверяет, существует ли допустимое соответствие. В моем коде я заполнил текстовый файл с подробной информацией, если файл не существует, и я удалю/обновлю его при добавлении нового настраиваемого имени. Я считаю, что это будет работать лучше, чем запрос базы данных каждый раз, так как у меня, вероятно, будет около 20 пар имя/значение здесь.
Так создать ограничение, как так
public class MyCustomRouteConstraint : IHttpRouteConstraint
{
private DbContext _context;
private static object fileLockObject = new object();
public MyCustomRouteConstraint()
{
_context = new DbContext();
}
public bool Match(System.Net.Http.HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
{
var appDataPath = System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/CustomNameRouteCache.txt");
// lock variable so no 2 or more threads can try to create file at once
lock (fileLockObject)
{
var list = new List<MyRouteModel>();
// check if our cache file exists, if not, lets create it
if (!File.Exists(appDataPath))
{
using (var writer = new System.IO.StreamWriter(appDataPath))
{
// get all modules
var names = _context.CustomNames.ToList();
foreach (var item in names)
{
list.Add(Mapper.Map<MyRouteModel>(item));
}
// serialize the list to the file in json format
var json = JsonConvert.SerializeObject(list);
// write to file
writer.Write(json);
};
}
else
{
// open file and get json contents
using (var reader = new System.IO.StreamReader(appDataPath))
{
var json = reader.ReadToEnd();
list = JsonConvert.DeserializeObject<List<MyRouteModel>>(json);
}
}
// lets search our list and see if this value is in our modules
foreach (var item in list)
{
if (item.Name.Equals(values[parameterName].ToString()))
{
return true;
}
}
}
return false;
}
}
Теперь это, кажется, работает отлично, я могу назвать MyController, используя следующие пути, или любые другие, которые создаются пользователем во время выполнения
api/company/
api/contact/
api/project/
api/whateveryouwant/
Надеюсь, что это поможет кому-то еще попытаться сделать что-то подобное.
Я не знаю этих типов объектов до выполнения, поэтому я не могу их кодировать, но мне нужен способ «перенаправить» во время выполнения на основе значения. – Gillardo
Знаете ли вы те, что не из db? если да, см. мой ответ. Это в основном обратный ответ. –
Если вы не знаете точных имен, система не сможет найти имя метода. Вы можете преобразовать свои имена в дополнительные параметры URI и указать один специальный маршрут для этого: –