2013-02-28 4 views
5

У меня есть следующий код, но запрос концы (Foo()/Bar()) всегда в No action was found on the controller 'Device' that matches the request.ASP.NET WebAPI - никаких действий не было найдено

Я пользовательский маршрут в моем WebApiConfig:

config.Routes.MapHttpRoute(
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{action}/{id}", 
    defaults: new {id = RouteParameter.Optional} 
    ); 

моего ASP.NET WebAPI контроллер:

[HttpPost] 
public void UpdateToken(string newToken) 
{ 
    _deviceHandler.UpdateToken(newToken); 
} 

Чтобы запросить мой ASP.NET WebAPI Я использую RestSharp.

private static void Send(string resource, Method method, object payload) 
{ 
    var client = new RestClient(baseUrl); 
    var request = new RestRequest(resource, method); 
    request.XmlSerializer = new JsonSerializer(); 
    request.RequestFormat = DataFormat.Json; 
    request.AddBody(payload); 

    var response = client.Execute(request); 
    // ... handling response (exceptions, errors, ...) 
} 

public void Foo() 
{ 
    var newToken = "1234567890"; 
    Send("/api/device/updatetoken", RestSharp.Method.POST, newToken); 
} 

public void Bar() 
{ 
    var newToken = new { newToken = "1234567890" }; 
    Send("/api/device/updatetoken", RestSharp.Method.POST, newToken); 
} 

Единственный способ избежать этой ошибки создает класс-оболочку со свойством (получить; набор;) в нем, который имеет имя аргумента контроллера (newToken).

У меня есть много запросов, которые отправляют одну или две пользовательские строки (неопределенная длина) в виде сообщения (получение ограничено по длине). Но для создания для каждого сценария реализация оболочки является реальным издержками! Я ищу еще один способ пойти.

PS: Я надеюсь, что я не сделал ни одной ошибки, упростив сценарий =)

ответ

12

Примитивов по умолчанию связаны с URI. Если вы хотите примитивные прийти от тела, вы должны использовать [FromBody] атрибут, как это:

[HttpPost] 
public void UpdateToken([FromBody] string newToken) 
{ 
    _deviceHandler.UpdateToken(newToken); 
} 

строку затем будет десериализованным с помощью соответствующего форматирования. Если это JSON, тело запроса должно выглядеть так:

"1234567890" 
+0

Спасибо, только недостающий [FromBody] -Атрибут был ошибкой. – dannyyy

+0

Это просто спасло мою ночь. Я ударился головой о том, почему этот конкретный маршрут получает 404. Он принимает int, где остальные мои маршруты берут ссылочный тип. Добавление атрибута [FromBody] выполнило трюк. – squillman

+0

1 для спасения моей половины дня моей жизни, половина уже потрачена на это спасибо –