Nessuno degli esempi sopra ha funzionato per le mie esigenze personali. Di seguito è quello che ho finito per fare.
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;
}
Per utilizzare quanto sopra nel percorso utilizzare:
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) });
Ciò che accade è il tipo di vincolo di falsi nel metodo in modo che questa route corrisponda solo ai metodi GET, POST, PUT e DELETE predefiniti. Il "vero" dice che vogliamo verificare la corrispondenza degli elementi nella matrice. Se fosse falso, diresti di escludere quelli nello str. Puoi quindi usare route sopra questo metodo predefinito come:
config.Routes.MapHttpRoute("GetStatus", "{controller}/status/{status}", new { action = "GetStatus" });
Quanto sopra è essenzialmente alla ricerca del seguente URL => http://www.domain.com/Account/Status/Active
o qualcosa del genere.
Al di là di quanto sopra non sono sicuro che diventerei troppo pazzo. Alla fine della giornata dovrebbe essere per risorsa. Ma vedo la necessità di mappare gli URL amichevoli per vari motivi. Sono abbastanza sicuro mentre si evolve Web Api ci sarà una sorta di disposizione. Se il tempo costruirò una soluzione più permanente e pubblicherò.