Ich versuche HTTP-Methodenüberschreibung nach den Schritten here zu implementieren implementieren. Im Grunde erstelle ich einen DelegatingHandler, ähnlich dem folgenden, und füge es als Nachrichtenhandler unter Application_Start
hinzu.X-HTTP-Method-Override gibt NotFound (404) auf ASP.NET-Web-API
public class MethodOverrideHandler : DelegatingHandler
{
readonly string[] _methods = { "DELETE", "HEAD", "PUT" };
const string _header = "X-HTTP-Method-Override";
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// Check for HTTP POST with the X-HTTP-Method-Override header.
if (request.Method == HttpMethod.Post && request.Headers.Contains(_header))
{
// Check if the header value is in our methods list.
var method = request.Headers.GetValues(_header).FirstOrDefault();
if (_methods.Contains(method, StringComparer.InvariantCultureIgnoreCase))
{
// Change the request method.
request.Method = new HttpMethod(method);
}
}
return base.SendAsync(request, cancellationToken);
}
}
Ich habe die folgenden Methoden definiert auf meinem Controller:
persons/{id}
, GETpersons/{id}
, PUTpersons/{id}
, DELETE
ich anrufen kann sie durch ihre "native" Methoden und sie funktionieren wie erwartet. Wenn ich jedoch versuche, sie über einen POST anzurufen und den Header X-HTTP-Method-Override
mit "DELETE" oder "PUT" zu senden, wird ein Fehler Not Found (404) angezeigt. Es ist wichtig hinzuzufügen, dass, wenn es diesen Fehler gibt, es niemals die MethodOverrideHandler
erreicht - ich habe einen Haltepunkt gesetzt, der nie getroffen wird; Es trifft den Haltepunkt, wenn ich normale DELETE und PUT anrufe.
ich auch versucht, indem eine andere Methode:
persons/{id}
, POST
Wenn ich das tue, erhalte ich eine Methode nicht erlaubt (405) statt.
Ich dachte, dass Nachrichtenhandler VOR dem Routing und Controller Dispatcher ausgeführt wurden. Warum gibt mir das 404?
Ich glaube nicht, dass dies verwandt ist, aber ich verwende nicht Standard-Web-API-Routing. Stattdessen bin ich Zuordnen eines benutzerdefinierten Attribut verwenden, um jede Methode zugewiesen, wie folgt aus:
routes.MapHttpRoute(
String.Format("{0}_{1}", operation.Name, service.ServiceId),
String.Format("{0}/{1}", service.RoutePrefix, routeTemplateAttribute.Template),
defaults,
new { httpMethod = GetHttpMethodConstraint(operation) });
[HttpDelete, RouteTemplate("persons/{id}")]
public HttpResponseMessage DeletePerson(string id)
{
// ...
}
EDIT: GetHttpMethodConstraint
Code ist unten.
private static HttpMethodConstraint GetHttpMethodConstraint(MethodInfo methodInfo)
{
var methodResolver = HttpMethodResolver.FromMethodInfo(methodInfo);
return new HttpMethodConstraint(methodResolver.Resolve());
}
internal class HttpMethodResolver
{
private MethodInfo _methodInfo;
private HttpMethodResolver(MethodInfo methodInfo)
{
_methodInfo = methodInfo;
}
public static HttpMethodResolver FromMethodInfo(MethodInfo methodInfo)
{
return new HttpMethodResolver(methodInfo);
}
public string[] Resolve()
{
var verbs = new List<HttpMethod>();
if (MethodHasAttribute<HttpGetAttribute>())
{
verbs.Add(HttpMethod.Get);
}
else if (MethodHasAttribute<HttpPostAttribute>())
{
verbs.Add(HttpMethod.Post);
}
else if (MethodHasAttribute<HttpDeleteAttribute>())
{
verbs.Add(HttpMethod.Delete);
}
else if (MethodHasAttribute<HttpPutAttribute>())
{
verbs.Add(HttpMethod.Put);
}
else
{
throw new ServiceModelException("HTTP method attribute should be used");
}
return verbs.Select(v => v.Method).ToArray();
}
private bool MethodHasAttribute<T>() where T : Attribute
{
return GetMethodAttribute<T>() != null;
}
private T GetMethodAttribute<T>() where T : Attribute
{
return _methodInfo.GetCustomAttributes(typeof(T), true).FirstOrDefault() as T;
}
}
Haben Sie versucht, Ihre Aktion-Methode von 'DeletePerson' zu' delete' zu ändern? –
Ich antwortete unten, aber wenn Sie Ihre Anwendung zippen und irgendwo ablegen können, kann ich einen Blick darauf werfen, da ich Ihr Problem nicht reprosieren konnte. – tugberk
Nur zur Erinnerung, mein Problem wurde durch diese Antwort geklärt: http://stackoverflow.com/a/13959148/1288760. – alextercete