2013-04-29 5 views
2

J'ai un certain contrôleur api avec cette action:Asp action async Api Web - erreur 404

public class ProxyController : ApiController { 
    public async Task<HttpResponseMessage> PostActionAsync(string confirmKey) 
    { 
     return await Task<HttpResponseMessage>.Factory.StartNew(() => 
       { 
        var result = GetSomeResult(confirmKey); 
        return Request.CreateResponse(HttpStatusCode.Created, result); 
       }); 
    } 
} 

Et voici mon cheminement api confuguration:

routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional }); 

Lorsque je tente de faire des Envoyer/Obtenir des demandes à cette action, elle renvoie l'erreur '404'. Comment puis-je le réparer? Toutes les autres actions non-asynchrones de ce contrôleur fonctionnent correctement.

UPD. Requête JS:

$.ajax({ 
     url: Url + '/api/Proxy/PostActionAsync', 
     type: 'POST', 
     data: { confirmKey: that.confirmKey },     
     dataType: 'json',     
     xhrFields: { withCredentials: true }, 
     success: function (data) { 
      ............ 
     }, 
     error: function (jqXHR, textStatus, errorThrown) { 
      ............ 
     }       
}); 

UPD. Résolu en ajoutant [FromBody] à mes paramètres dans la méthode d'action comme dans la réponse de J. Steen, il est maintenant l'air est comme

public class ProxyController : ApiController { 
     public async Task<HttpResponseMessage> PostActionAsync([FromBody]string confirmKey) 
     { 
      var someModel = new SomeResultModel(User.Identity.Name); 
      await Task.Factory.StartNew(() => someModel.PrepareModel(confirmKey)); 

      return Request.CreateResponse(HttpStatusCode.OK, someModel); 
     } 
    } 

Et ça marche!

+0

Postez aussi votre méthode 'ActionResult' et le nom du contrôleur. Si possible, votre appel asynchrone appelant Jquery aussi., :) – RajeshKdev

+0

ajouté tout requis –

+0

@IgorKonopko: Essayez de marquer l'action avec '[HttpPost]' – Catalin

Répondre

3

La configuration de routage pour l'API Web fonctionne un peu différemment de MVC.

Essayez

routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional }); 

Notez le manque {action} comme cela est résolu par l'API Web à l'appel en temps, automagiquement, selon le verbe HTTP que vous utilisez pour votre demande.

Tenir compte this article on Web API routing qui énumère (à titre d'exemple):

HTTP Method URI Path   Action   Parameter 
GET   api/products  GetAllProducts (none) 
GET   api/products/4  GetProductById 4 
DELETE  api/products/4  DeleteProduct 4 

Dans votre cas, la version async d'une action est également résolu automatiquement.

POST   api/products  PostActionAsync (Post data) 

Puisque nous savons maintenant le nom du contrôleur, les demandes seraient comme:

GET api/proxy 
GET api/proxy/4 
POST api/proxy (with post data) 

Modifier:

Après des recherches supplémentaires (bref, je l'avoue) j'ai trouvé le problème.

Vous devez ajouter [FromBody] devant votre in-parameter.

public async Task<HttpResponseMessage> PostActionAsync([FromBody] string confirmKey) 

Ceci, combiné avec l'envoi d'juste la valeur (pas JSON d'emballage) fonctionne à merveille. Définissez le type de contenu sur "application/x-www-form-urlencoded" au lieu de json et envoyez votre paramètre sous la forme "=" + that.confirmKey.

Alternative:

Si vous ne voulez pas bricoler avec des types de contenus et préfixant = -signs, juste l'envoyer dans le cadre du querystring. Oubliez le [FromBody] et le reste.Appelez

/api/Proxy/PostActionAsync?confirmKey=' + that.confirmKey 

Additional, exhaustive information in this blog.

+0

J'ai changé de routage comme à l'exemple youre, aussi mon client ajax url changé à ServerUrl + '/ api/Proxy? action = PostActionAsync', maintenant il renvoie 500 (Erreur interne du serveur). Est-ce que je dois utiliser seulement une action get/post/put dans un contrôleur api? –

+0

La convention est d'utiliser un seul POST par contrôleur. Aussi,? Action = PostActionAsync ne fonctionnera probablement pas non plus, je suis désolé de le dire. =/ –

+0

Je suis follement confus. Si vous voulez un routage basé sur l'action, ma réponse est fausse. Votre route-config doit être comme vous l'avez initialement déclaré. –

1

Est-ce que ce changement est possible?

public async Task<HttpResponseMessage> PostActionAsync() 
{ 
    var result = await GetSomeResult(); 
    return Request.CreateResponse(HttpStatusCode.Created, result); 
} 
+0

'CreateResponse()' renvoie ' HttpResponseMessage ', qui ne peut pas être converti en' Task ' –

+0

'tâche asynchrone WaitAsynchronouslyAsync() {wait Task.Delay (10000); retour "Terminé"; } 'Ceci est un exemple de [MSDN] (http://msdn.microsoft.com/en-us/library/vstudio/hh156528.aspx). – Vladimir

+0

Voici le code actuel http://pastebin.com/9pda4BPb et il renvoie toujours '404' –