2013-04-29 4 views
2

У меня есть апи контроллер с этим действием:Asp Web Api асинхронное действие - 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); 
       }); 
    } 
} 

А вот мой confuguration апите маршрутизации:

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

Когда я пытаюсь сделать любого Post/Get Requests для этого действия, он возвращает ошибку «404». Как я могу это исправить? Все остальные неасинхронные действия в этом контроллере работают нормально.

UPD. 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. Решено путем добавления [FromBody] к моим параметрам в методе действия так же, как в ответ Дж Стина, теперь выглядят как

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); 
     } 
    } 

И это работает!

+0

Также введите имя метода ActionResult и имя контроллера. Если возможно, ваш асинхронный вызов JQuery тоже., :) – RajeshKdev

+0

добавил все необходимое –

+0

@IgorKonopko: попробуйте отметить действие с помощью '[HttpPost]' – Catalin

ответ

3

Конфигурация маршрутизации для Web API работает несколько иначе, чем MVC.

Попробуйте

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

Примечания недостающего {action} как решаются Web API на время вызова, автоматически, в зависимости от HTTP глагола вы используете для вашего запроса.

Рассмотрим this article on Web API routing, которые перечислены (в качестве примера):

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

В вашем случае, версия асинхронной в действии также разрешаются автоматически.

POST   api/products  PostActionAsync (Post data) 

Так как мы теперь знаем имя контроллера, запросы будут как:

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

Edit:

После дополнительных исследований (Короче говоря, я признаю), я нашел проблема.

Вам необходимо добавить [FromBody] infront вашего параметра.

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

Это, в сочетании с отправкой только значение (без переноса) JSon творит чудеса. Задайте тип контента «application/x-www-form-urlencoded» вместо json и отправьте свой параметр как "=" + that.confirmKey.

Альтернатива:

Если вы не хотите возиться с контент-типов и префиксов = -signs, просто отправить его как часть строки запроса. Забудьте [FromBody], а остальное.Звонок

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

Additional, exhaustive information in this blog.

+0

Я изменил маршрутизацию, как на вашем примере, также мой клиент ajax url изменен на ServerUrl + '/ api/Proxy? action = PostActionAsync', теперь он возвращает 500 (Internal Server Error). Является ли это мерилом, что я должен использовать только одно действие get/post/put в одном контроллере api? –

+0

Соглашение должно использовать только один POST на контроллер. Кроме того, «action = PostActionAsync, вероятно, тоже не сработает», извините. =/ –

+0

Я дико смущен. Если вы хотите маршрутизацию на основе действий, мой ответ неверен. Ваш маршрут-config должен быть таким, как вы изначально заявляли. –

1

Это изменение возможно?

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

'CreateResponse()' возвращает ' HttpResponseMessage ', который не может быть преобразован в «Задача » –

+0

'async Задача WaitAsynchronouslyAsync() {ожидание Task.Delay (10000); return «Finished»; } 'Это пример из [MSDN] (http://msdn.microsoft.com/en-us/library/vstudio/hh156528.aspx). – Vladimir

+0

Вот текущий код http://pastebin.com/9pda4BPb, и он по-прежнему возвращает '404' –

Смежные вопросы