Ninguno de los ejemplos anteriores funcionó para mis necesidades personales. Lo siguiente es lo que terminé haciendo.
public class ContainsConstraint : IHttpRouteConstraint
{
public string[] array { get; set; }
public bool match { get; set; }
/// <summary>
/// Check if param contains any of values listed in array.
/// </summary>
/// <param name="param">The param to test.</param>
/// <param name="array">The items to compare against.</param>
/// <param name="match">Whether we are matching or NOT matching.</param>
public ContainsConstraint(string[] array, bool match)
{
this.array = array;
this.match = match;
}
public bool Match(System.Net.Http.HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
{
if (values == null) // shouldn't ever hit this.
return true;
if (!values.ContainsKey(parameterName)) // make sure the parameter is there.
return true;
if (string.IsNullOrEmpty(values[parameterName].ToString())) // if the param key is empty in this case "action" add the method so it doesn't hit other methods like "GetStatus"
values[parameterName] = request.Method.ToString();
bool contains = array.Contains(values[parameterName]); // this is an extension but all we are doing here is check if string array contains value you can create exten like this or use LINQ or whatever u like.
if (contains == match) // checking if we want it to match or we don't want it to match
return true;
return false;
}
Para usar lo anterior en su ruta use:
config.Routes.MapHttpRoute("Default", "{controller}/{action}/{id}", new { action = RouteParameter.Optional, id = RouteParameter.Optional}, new { action = new ContainsConstraint( new string[] { "GET", "PUT", "DELETE", "POST" }, true) });
Lo que sucede es el tipo de restricción de falsificaciones en el método para que esta ruta solo coincida con los métodos predeterminados GET, POST, PUT y DELETE. El "verdadero" dice que queremos verificar si hay una coincidencia de los elementos en la matriz. Si fuera falso, estaría diciendo que excluya a los que están en la cadena.Puede usar rutas por encima de este método predeterminado como:
config.Routes.MapHttpRoute("GetStatus", "{controller}/status/{status}", new { action = "GetStatus" });
En lo anterior, esencialmente está buscando la siguiente URL => http://www.domain.com/Account/Status/Active
o algo así.
Más allá de lo anterior, no estoy seguro de volverme loco. Al final del día, debe ser por recurso. Pero sí veo la necesidad de mapear las URL amigables por varias razones. Me siento bastante seguro a medida que Web Api evoluciona, habrá algún tipo de provisión. Si es tiempo, construiré una solución más permanente y publicaré.