Использование 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 ответов


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


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

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

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

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}. Спасибо всем за Ваш вклад.