it-swarm.com.ru

Использование Fiddler для отправки POST запрос к веб-API

Я пишу простую программу WebApi, используя C #. (Я хорошо знаю MVC, но я новичок в WebApi.) Он содержит контроллер Vendors (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] и поместил имя пользователя = tapuser в тело запроса. На этот раз, когда я отправил запрос, tapuser не был передан в действие. Аргумент GetVendor () был нулевым. Я пробовал варианты в теле запроса, такие как {"username": "tapuser"}, но это не помогает. Я также пытался изменить маршрут различными способами, например, изменил routeTemplate на «api/{controller}/{action}/{id}». Это тоже не помогло. Я уверен, что упускаю что-то очень простое, но я просто не вижу этого.

7
Tim

Попробуйте ввести свое значение непосредственно в тело запроса. Видеть это.  enter image description here

14
drunkcoder

Теперь я сделал некоторую отладку и смог воссоздать проблему, с которой вы столкнулись. 

В итоге я смог получить данные для действия, выполнив следующие действия:

Сначала я создал класс, который будет действовать как контейнер для полезной нагрузки.

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 будет использовать форматтер медиа-типа для чтения значение имени из тела запроса. Вот пример клиента запрос.

POST http://localhost:5076/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:5076
Content-Type: application/json
Content-Length: 7

"Alice"

Когда параметр имеет значение [FromBody], веб-API использует заголовок Content-Type выбрать форматтер. В этом примере тип содержимого - «application/json», а тело запроса - это необработанная строка JSON (не объект JSON).

Не более одного параметра разрешено читать из тела сообщения. Так Это не будет работать:

// Caution: Will not work!    
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

Причина этого правила заключается в том, что тело запроса может храниться в небуферизованный поток, который может быть прочитан только один раз.

Когда я отменил свои первоначальные изменения и последовал примеру, это сработало как задумано.

Надеюсь это поможет.

1
Nkosi

Я обнаружил, что, если я помещаю 'tapuser' в тело запроса, используя одинарные или двойные кавычки, это работает. Цитаты, кажется, ответ. Если я помещаю что-либо кроме tapuser в кавычки, все это передается в качестве аргумента. Например, {username = tapuser} будет передан как {username = tapuser}. Спасибо всем за ваш вклад.

1
Tim