#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-api3. Кстати, 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.