Веб-API: содержимое всегда равно нулю

#c# #asp.net-web-api

#c# #asp.net-web-api

Вопрос:

Я пытаюсь разработать веб-API, и когда я тестирую метод POST, тело всегда имеет значение null. Я перепробовал все при отправке запроса:

 HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:1748/api/SomeAPI");
req.Method = "post";;

var aaa = Encoding.Default.GetBytes("Test");
req.ContentType = "application/xml";
req.ContentLength = aaa.Length;
req.GetRequestStream().Write(aaa, 0, aaa.Length);

HttpWebResponse res = (HttpWebResponse)req.GetResponse();
using (System.IO.StreamReader sr = new System.IO.StreamReader(res.GetResponseStream())) {
    Console.WriteLine(sr.ReadToEnd());
}
 

Я использую точку останова, и API вызывается правильно, но элемент тела всегда имеет значение null:

 [HttpPost]
public void Post([FromBody]String test) {

}
 

Комментарии:

1. Ранее я разделил GetRequestStream(), чтобы я мог вызвать Close() для него.

2. @RobLang: я уже пробовал это, но все равно получаю null

3. Попробуйте использовать HTTP-анализатор, подобный снифферу, для проверки вашего запроса, похоже, что с запросом что-то не так. Вы можете попробовать использовать chrome advance rest client для отправки образца запроса.

4. @Vladimir: Тело является частью запроса, но теперь извлекается веб-api

5. Просто любопытно, вы уже пробовали отлаживать конец API, чтобы узнать, какой запрос. Как выглядит содержимое? Вы должны иметь возможность хотя бы взглянуть и посмотреть, соответствует ли длина тому, что вы ожидаете. Если длина совпадает, Web API, вероятно, просто не извлекает данные в ваш параметр автоматически.

Ответ №1:

попробуйте

 [HttpPost]
public void SomeApi()
{
   var test = HttpContext.Current.Request.Form["Test"];
}
 

Если вы правильно отправите значение, это сработает на 100%

Ответ №2:

Для вашего типа контента задано значение XML, поэтому вы должны передавать данные в формате XML. Это означает перенос ваших данных в <string> элемент.

Я бы рекомендовал использовать RestSharp (http://restsharp.org /) для выполнения вызовов WebAPI из .Net.

         var client = new RestClient("http://localhost:1748/");
        var request = new RestRequest("api/SomeAPI", Method.POST);
        request.AddBody("Test");
        var response = client.Execute(request);
 

Обновить

Я создал пример проекта, и он работает абсолютно нормально:

На стороне сервера:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;

namespace WebApplication1.Controllers
{
    public class HomeController : ApiController
    {
        [Route("api/TestAPI")]
        [HttpPost]
        public IHttpActionResult Post([FromBody]String test)
        {
            return Ok(string.Format("You passed {0}.", test));
        }
    }
}
 

На стороне клиента:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:1748/api/TestAPI");
            req.Method = "post"; ;
            var aaa = Encoding.Default.GetBytes(""Test"");
            req.ContentType = "application/json";
            req.ContentLength = aaa.Length;
            req.GetRequestStream().Write(aaa, 0, aaa.Length);
            HttpWebResponse res = (HttpWebResponse)req.GetResponse();
            using (System.IO.StreamReader sr = new System.IO.StreamReader(res.GetResponseStream()))
            {
                Console.WriteLine(sr.ReadToEnd());
            }
        }
    }
}
 

После установки службы WEB API в IIS и запуска консольного приложения он печатает:

"You passed Test."

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

 var aaa = Encoding.Default.GetBytes("<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Test</string>");
 

Ответ, который вы получите, это

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">You passed Test.</string>

Оба образца в отладчике будут иметь правильное значение, переданное в параметре test.

Комментарии:

1. На самом деле не имеет значения, является ли это XML, JSON, обычный текст. Важно то, что тело всегда равно нулю, несмотря ни на что. Я подозреваю, что это ошибка или что-то в этом роде.

2. В вашем примере тело будет Test . Когда он достигнет сервера, его нужно будет десериализовать. Поскольку тип содержимого — XML, он попытается интерпретировать его как XML и потерпит неудачу, поэтому он предположит, что вы не передали никаких данных, и передаст NULL вашему методу. Если вы хотите получить доступ к необработанному содержимому вашего тела (т.Е. К строке), пожалуйста, прочтите эту статью: https://weblog.west-wind.com/posts/2013/dec/13/accepting-raw-request-body-content-with-aspnet-web-api

3. Кстати, JSON завершится ошибкой по той же причине — в JSON строки заключены в кавычки, поэтому для того, чтобы заставить его работать с JSON, вам нужно использовать var aaa = Encoding . По умолчанию. getBytes(«»Test»»); Затем ваш метод получит Test

4. Это не работает, и, похоже, это ошибка. Я нашел тему в Gidhub, указывающую, что это ошибка. Это не имеет абсолютно никакого отношения к типу содержимого, если это проблема, вы получите сообщение об ошибке not null value 🙂

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

Ответ №3:

Две вещи, которые нужно попробовать: 1. попробуйте выполнить ваш запрос с помощью проверенного и проверенного инструмента, такого как Postman. Это исключит любую вероятность того, что ваш запрос каким-либо образом искажен. 2-й, попробуйте изменить свой ContentType на text / plain . Возможно, конвейер запросов видит application / xml, но тело вашего запроса является недопустимым xml, который действительно должен быть плохим запросом, но просто сериализуется как null.