Использование Fiddler для отправки запроса POST в WebApi
Я пишу простую программу WebApi, используя C#. (Я знаю MVC довольно хорошо, но я новичок в WebApi.) Он содержит контроллер поставщиков (VendorsController.cs), который содержит действие "getvendor", как показано в примере кода ниже:
[RoutePrefix("api/vendors")]
public class VendorsController : ApiController
{
[Route("getvendor"), HttpPost]
public TAPUser GetVendor([FromBody] string username)
{
Int32 userid = -1;
...
маршруты настроены следующим образом:
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional
);
Я использую Fiddler для тестирования программы. Во-первых, я запустил вышеуказанный код без [FromBody] и использовал Fiddler для отправки запроса POST с именем пользователя в url-адресе, как это: http://localhost:60060/api/vendors/getvendor?username=tapuser
этого работал нормально. tapuser был передан в качестве аргумента GetVendor, и действие вернуло ожидаемый результат.
затем я добавил [FromBody] и поместил username=tapuser в тело запроса. На этот раз, когда я отправил запрос, tapuser не был передан действию. Аргумент GetVendor () был равен null. Я пробовал варианты тела запроса, такие как { "username": "tapuser"}, но это не помогает. Я также пытался изменить маршрут различными способами, например, изменить routeTemplate на "api/{controller}/{action}/{id}". Это тоже не помогло. Я уверен, что упускаю что-то очень простое, но я просто не вижу этого.
3 ответов
теперь я сделал некоторую отладку и смог воссоздать проблему, с которой вы столкнулись.
в конечном итоге я смог получить данные для действия, выполнив следующее:
сначала я создал класс, чтобы действовать как контейнер для полезной нагрузки.
public class body {
public string username { get; set; }
}
и обновил действие, чтобы соответствовать
[Route("getvendor"), HttpPost]
public TAPUser GetVendor([FromBody] body payload) {...}
затем с помощью fiddler я компостировал запрос к конечной точке для тестирования.
POST http://localhost:60060/api/vendors/getvendor HTTP/1.1
User-Agent: Fiddler
Host: localhost:60060
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Content-Length: 16
username=tapuser
когда моя точка разрыва была поражена, тело / полезная нагрузка была заполнена с именем пользователя как tapuser.
обновление
теперь, когда вышеизложенное работало, я не был полностью уверен, что это решило вашу проблему, поэтому я сделал некоторые гуглить и наткнулся на это
привязка параметров в ASP.NET Web API
где это показало следующий пример использования [FromBody]
чтобы заставить Web API читать простой тип из тела запроса, добавьте [FromBody] атрибут параметр:
public HttpResponseMessage Post([FromBody] string name) { ... }
в этом примере Web API будет использовать форматер типа носителя для чтения значение name из тела запроса. Вот пример клиента запрос.
POST http://localhost:5076/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:5076
Content-Type: application/json
Content-Length: 7
"Alice"
когда параметр имеет [FromBody], Web API использует заголовок Content-Type чтобы выбрать форматер. В этом примере тип содержимого "application/ json", а тело запроса является необработанной строкой JSON (не объект JSON.)
At большинство параметров разрешено считывать из тела сообщения. Так это не сработает:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
причина этого правила заключается в том, что тело запроса может храниться в небуферизованный поток, который можно прочитать только один раз.
когда я вернул свои первоначальные изменения и последовал примеру, он работал по назначению.
надеюсь, что это помогает.
Я обнаружил, что если я помещаю "tapuser" в тело запроса, используя одинарные или двойные кавычки, он работает. Цитаты, кажется, ответ. Если я помещаю что-то другое, кроме tapuser внутри кавычек, все это передается как аргумент. Например, '{username=tapuser} ' будет передан как {username=tapuser}. Спасибо всем за Ваш вклад.