2010-09-02 4 views
2

J'ai examiné presque tous les problèmes WCF Rest PUT/POST sur SO ici et n'ai toujours pas pu déterminer pourquoi je suis incapable PUT ou POST à ​​mon service Web, mais je suis en mesure d'appeler une méthode de test GetTime via GET.Comment résoudre WCF Rest MethodNotFound (405) Erreur lors de l'ajout à PUT via WCF Rest Starter Kit HttpClient

Ce service particulier échange des informations d'identification personnalisées (nom d'utilisateur, mot de passe et autres informations) pour un jeton. Ces informations de jeton sont cryptées et ajoutées à l'en-tête des demandes ultérieures à d'autres services Web, de sorte que le nom d'utilisateur/les mots de passe ne doivent pas être transmis partout.

Tous les appels de service Web sont toujours traités comme sans état, mais nécessitent ces informations d'en-tête auth plutôt que le nom d'utilisateur/mots de passe pour accéder aux opérations de service sécurisées.

contrat

[ServiceContract(Namespace = "")] 
public interface IUserService 
{ 
    [WebInvoke(Method = "PUT", UriTemplate = "users/{username}/session")] 
    [WebHelp(Comment = "Creates a new session for the specified username")] 
    [OperationContract] 
    AuthToken PutSession(string username, CustomCredential credential); 
    ... 

    [WebInvoke(Method = "GET", UriTemplate = "time")] 
    [WebHelp(Comment = "Test method; returns the time")] 
    [RequireAuthToken] 
    [OperationContract] 
    DateTime GetTime(); 
} 

service Impelementation

public class UserService : IUserService 
{ 
    #region UserService Members 
    public AuthToken PutSession(string username, CustomCredential credential) 
    { 
     // ... 
    } 

    public DateTime GetTime() 
    { 
     return DateTime.Now; 
    } 
} 

Code d'essai

[Fact] 
    public void When_Authenticated_And_Getting_Time_Expect_200_Status() 
    { 
     // arrange 
     using (var client = Get_HttpClient_With_AuthHeaders()) { 

      // act 
      var result = client.Get("time"); 

      // assert 
      Assert.Equal(HttpStatusCode.OK, result.StatusCode); 
     } 
    } 

Le GetTime mentionné ci-dessus fonctionne (juste une méthode de test j'ai ajouté).

[Fact] 
    public void When_PuttingSession_Expect_AuthToken_Is_Returned() 
    { 
     // arrange 
     using (var client = Get_HttpClient_With_No_Auth_Headers()) { 

      var cred = new CustomCredential("test", "password", 1); 
      var content = HttpContentExtensions.CreateDataContract<CustomCredential>(cred); 

      // act 
      HttpResponseMessage response = client.Put("users/test/session", content); 

      // assert 
      response.EnsureStatusIsSuccessful(); 
      Assert.Equal(HttpStatusCode.Created, response.StatusCode); 
      var authToken = response.Content.ReadAsDataContract<AuthToken>(); 
      Assert.NotNull(authToken); 
     } 
    } 

La vente ci-dessus retourne un MethodNotAllowed (405). Tout comme un autre test, j'ai ajouté un point de terminaison Mex au service, créé une nouvelle application de console et ajouté une «référence de service» à ce service. En utilisant le code proxy client généré, j'ai pu quelque chose de similaire à ....

IUserServiceClient client = new IUserServiceClient(); 
CustomCredential cred = ... 
AuthToken token = client.PutSession("test_username", cred); 

Ce que cela suggère est que ...

  • Le service web est hébergé dans IIS correctement
  • Je suis capable de consommer le service en utilisant le code client proxy SOAP généré
  • Je suis en mesure de consommer des demandes GET via plus conviviale HttpClient/reste toolkit
  • J'ai testé ce get dans un navigateur et il w
  • Pour une raison quelconque put et d'autres méthodes connexes (post, delete. etc) ne fonctionne pas via la boîte à outils de repos

Vous ne savez pas quelle est la cause de celui-ci.

EDIT

Je remarque aussi que IIS doit avoir créé cette web.config à la racine du site Web où les services sont hébergés qui semblent être en permettant aux principaux verbes HTTP.

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 
    <system.webServer> 
     <security> 
      <requestFiltering> 
      <verbs> 
       <add verb="PUT" allowed="true" /> 
       <add verb="GET" allowed="true" /> 
       <add verb="POST" allowed="true" /> 
       <add verb="DELETE" allowed="true" /> 
      </verbs> 
      <fileExtensions> 
       <add fileExtension=".svc" allowed="true" /> 
      </fileExtensions> 
     </requestFiltering> 
     </security> 
    </system.webServer> 
</configuration> 

J'ai également vérifié dans IIS 7 les applications de gestionnaire pour * .svc et vérifié que «tous les verbes sont activés.

Répondre

1

Vérifiez que le gestionnaire associé de .svc dans IIS est autorisé à traiter HTTP POST, PUT, DELETE. En cas de problèmes avec seulement PUT et DELETE, vérifiez que votre répertoire virtuel n'est pas configuré pour WebDAV (je pense qu'il s'agit d'un module HTTP).

+0

J'ai vérifié les mappages de gestionnaire pour * .svc et il a été configuré pour autoriser tous les verbes. Donc ça devrait aller. Comment vérifier ce dernier (que le répertoire virtuel soit ou non configuré pour WebDAV?) Ceci est dans mon environnement de test sur ma machine dev, donc l'emplacement de l'application hébergée dans IIS est en fait mon dossier de projet source SVN. Problème d'autorisations peut-être? –

+0

Ceci est étrange au moins HTTP POST devrait fonctionner sans problème, sauf si vous accédez à une mauvaise URL. WebDav est utilisé uniquement si vous l'avez installé (il s'agit de la fonction Windows sous IIS). Si le répertoire virtuel est configuré pour utiliser WebDav, il doit contenir WebDavModule dans sa configuration de module (cochez la case dans la console de gestion IIS). –

+0

Bon appel, après avoir remarqué que WebDav a été installé je suis allé à 'ajouter des fonctionnalités de suppression' et désinstallé ce module de IIS. Il semble avoir résolu mes problèmes de vente mentionnés ci-dessus. Je vais écrire d'autres tests pour vérifier les autres types de verbes Http demain. Je marque votre réponse comme fixe alors merci. Êtes-vous capable d'expliquer pourquoi WebDav a provoqué cela, alors je le sais à l'avenir? Encore une fois, merci. –

Questions connexes