HTTP PUT non autorisé dans l’API Web ASP.NET

Sur mon projet d’API Web, je ne peux pas exécuter de HTTP PUT sur mes ressources. J’ai lu des questions similaires sur ce problème et j’ai suivi les conseils recommandés.

Tout d’abord, j’ai complètement désinstallé WebDAV sur ma machine (Windows 7 64 bits), puis j’ai redémarré ma machine.

Deuxièmement, les gestionnaires WebDAV ont été spécifiés comme étant supprimés dans mon web.config et le verbe HTTP PUT été spécifié comme étant autorisé pour le gestionnaire d’URL sans extension.

            

J’ai même essayé d’append le gestionnaire d’URL ISAPI Extensionless (32 bits et 64 bits) et de changer mon application du pool d’applications de pipeline intégré au pool d’applications classique.

   

J’utilise actuellement Thinktecture IdentityModel pour activer la prise en charge du partage de ressources d’origine croisée (CORS). Pour ma santé mentale, je suis allé avec l’option nucléaire de tout activer pour s’assurer que le HTTP PUT est réellement autorisé.

 config.RegisterGlobal(httpConfig); config.ForAllResources() .ForAllOrigins() .AllowAllMethods() .AllowAllRequestHeaders(); 

Le package NuGet d’ atsortingbut Routing est configuré pour extraire tous les itinéraires de l’assembly actuel et de tous les sous-types d’ ApiController .

 config.AddRoutesFromAssembly(Assembly.GetExecutingAssembly()); config.AddRoutesFromControllersOfType(); 

Ma ressource possède également l’atsortingbut PUT correctement spécifié.

 [PUT("/API/Authenticate/Link/{key}/{identifier}")] public Boolean LinkUser(Guid key, Ssortingng identifier) { ... } 

Toutes les ressources consultées à ce sujet recommandent exactement la même chose: désinstaller WebDAV, désactiver les gestionnaires WebDAV et s’assurer que le gestionnaire d’URL Extensionless est correctement configuré. J’ai fait tout ça et ça ne marche toujours pas.

En tant que violoniste, je reçois ce qui suit:

 PUT https://localhost/Test/API/Authenticate/Link/Foo/Bar {"Message":"The requested resource does not support http method 'PUT'."} 

Qu’est-ce que je fais mal?

Apparemment, il existe un problème connu dans AtsortingbuteRouting dans lequel les méthodes HttpPut ne sont actuellement pas fonctionnelles dans l’API Web ASP.NET.

La solution de contournement actuellement acceptée consiste à append le verbe approprié sur l’itinéraire jusqu’à ce qu’un correctif correct apparaisse:

Web API RC a scellé une interface vitale pour la détection de routage par la structure sous-jacente. Bien que l’interface soit maintenant publique, la modification ne sera pas publiée avant vNext. Donc, voici quelques solutions de contournement:

  • Utilisez les atsortingbuts AR en combinaison avec les atsortingbuts HttpGet, HttpPost, HttpPut ou HttpDelete de System.Web.Http:
 [GET("some/url"), HttpGet] public ssortingng Method1() {} [PUT("some/url"), HttpPut] public ssortingng Method2() {} [POST("some/url"), HttpPost] public ssortingng Method3() {} [DELETE("some/url"), HttpDelete] public ssortingng Method4() {} 

Vérifiez que vous utilisez [HttpPut] dans System.Web.Http .

Dans certaines circonstances, vous pouvez utiliser l’atsortingbut de System.Web.Mvc.

Cela donnait 405s pour nous.

J’ai eu la même erreur, et l’a tracée à un itinéraire personnalisé que j’avais défini comme suit:

 config.Routes.MapHttpRoute( name: "SomeCall", routeTemplate: "api/somecall/{id}", defaults: new { controller = "SomeCall", action = "Get" } ); 

Le problème ici est l’ action = "Get" qui empêchait l’action PUT du même URI de répondre. Supprimer l’action par défaut a résolu le problème.

Ce qui a fonctionné pour moi a été d’append un atsortingbut de route, car j’en avais déjà un défini pour une demande GET surchargée comme suit:

  // GET api/Transactions/5 [Route("api/Transactions/{id:int}")] public Transaction Get(int id) { return _transactionRepository.GetById(id); } [Route("api/Transactions/{code}")] public Transaction Get(ssortingng code) { try { return _transactionRepository.Search(p => p.Code == code).Single(); } catch (Exception Ex) { System.IO.File.WriteAllText(@"C:\Users\Public\ErrorLog\Log.txt", Ex.Message + Ex.StackTrace + Ex.Source + Ex.InnerException.InnerException.Message); } return null; } 

J’ai donc ajouté pour le PUT:

  // PUT api/Transactions/5 [Route("api/Transactions/{id:int}")] public HttpResponseMessage Put(int id, Transaction transaction) { try { if (_transactionRepository.Save(transaction)) { return Request.CreateResponse(HttpStatusCode.Created, transaction); } } catch (Exception Ex) { System.IO.File.WriteAllText(@"C:\Users\Public\ErrorLog\Log.txt", Ex.Message + Ex.StackTrace + Ex.Source + Ex.InnerException.InnerException.Message); } return Request.CreateResponse(HttpStatusCode.InternalServerError, transaction); } 

Je pense que ce n’est plus le cas, peut-être que ce problème a été résolu maintenant. L’API Web ASP.NET MVC autorise désormais $ http.put et voici le code à tester.

AngularJS Code de script

 $scope.UpdateData = function () { var data = $.param({ firstName: $scope.firstName, lastName: $scope.lastName, age: $scope.age }); $http.put('/api/Default?'+ data) .success(function (data, status, headers) { $scope.ServerResponse = data; }) .error(function (data, status, header, config) { $scope.ServerResponse = htmlDecode("Data: " + data + "\n\n\n\nstatus: " + status + "\n\n\n\nheaders: " + header + "\n\n\n\nconfig: " + config); }); }; 

Code HTML

 

AngularJS Put request

First Name:

Last Name:

Age :


{{ ServerResponse }}

Méthode d’action du contrôleur API Web ASP.NET MVC

  public class DefaultController : ApiController { public HttpResponseMessage PutDataResponse(ssortingng firstName, ssortingng lastName, int age) { ssortingng msg = "Updated: First name: " + firstName + " | Last name: " + lastName + " | Age: " + age; return Request.CreateResponse(HttpStatusCode.OK, msg); } } 

(Changer l’URL à laquelle envoyer la demande) Lorsque nous cliquons sur le bouton Soumettre, il envoie la demande HttpPut à ‘/ api / default’ (DefaultController) où la méthode d’action PutDataResponse est déclarée. Cette méthode sera appelée et l’utilisateur obtiendra sa réponse.

Cette solution a été écrite à l’origine ici

Pour moi, c’était parce que je n’avais pas défini le type de média dans la chaîne de contenu json pour ma demande de client http:

new SsortingngContent (json, Encoding.UTF32, “application / json” );

Toutes sortes de comportements étranges si ce n’est pas défini.