c# - net - webapi post json null




web-api POST body object всегда null (11)

FromBody - странный атрибут, поскольку входные значения POST должны быть в определенном формате, чтобы параметр был непустым, если он не является примитивным типом. (студент здесь)

  1. Попробуйте свой запрос с {"name":"John Doe", "age":18, "country":"United States of America"} как json.
  2. Удалите [FromBody] и попробуйте решение. Он должен работать для не-примитивных типов. (студент)
  3. С атрибутом [FromBody] другой параметр должен отправлять значения в формате =Value Формат, а не в формате key=value . Это означало бы, что ваша ключевая ценность student должна быть пустой строкой ...

Существуют также другие варианты написания настраиваемого связующего объекта для класса ученика и атрибута параметра с помощью настраиваемого связующего.

Я все еще изучаю веб-API, поэтому простите меня, если мой вопрос звучит глупо.

У меня это в моем StudentController :

public HttpResponseMessage PostStudent([FromBody]Models.Student student)
        {
            if (DBManager.createStudent(student) != null)
                return Request.CreateResponse(HttpStatusCode.Created, student);
            else
                return Request.CreateResponse(HttpStatusCode.BadRequest, student);
        }

Чтобы проверить, работает ли это, я использую расширение Google Chrome «Почтальон» для создания запроса HTTP POST для его проверки.

Это мой необработанный запрос POST:

POST /api/Student HTTP/1.1
Host: localhost:1118
Content-Type: application/json
Cache-Control: no-cache

{"student": [{"name":"John Doe", "age":18, "country":"United States of America"}]}

"student" должен быть объектом, но когда я отлаживаю приложение, API получает объект-ученик, но контент всегда равен NULL .


В моем случае проблемой был объект DateTime я отправлял. Я создал DateTime с «yyyy-MM-dd» и DateTime который был необходим объекту, который я сопоставлял с необходимыми «HH-mm-ss». Поэтому добавление «00-00» решило проблему (из-за этого полный элемент был пустым).


Если вы используете Postman, убедитесь, что:

  • Вы установили заголовок «Content-Type» в «application / json»
  • Вы отправляете тело как "сырое"
  • Вам не нужно указывать имя параметра в любом месте, если вы используете [FromBody]

Я глупо пытался отправить свой JSON в виде данных формы, а ...


Если любое из значений объекта JSON запроса не является тем же типом, что и ожидалось службой, то аргумент [FromBody] будет равен null .

Например, если свойство age в json имеет значение float :

«Возраст»: 18,0

но служба API ожидает, что она будет int

"Возраст": 18

то student будет равен null . (В ответе не будет отправлено сообщений об ошибках, если не будет проверки нулевой ссылки).


Может быть полезно добавить TRACING в сериализатор json, чтобы вы могли видеть, что происходит, когда что-то идет не так.

Определите реализацию ITraceWriter, чтобы показать их вывод отладки, например:

class TraceWriter : Newtonsoft.Json.Serialization.ITraceWriter
{
    public TraceLevel LevelFilter {
        get {
            return TraceLevel.Error;
        }
    }

    public void Trace(TraceLevel level, string message, Exception ex)
    {
        Console.WriteLine("JSON {0} {1}: {2}", level, message, ex);
    }
}

Затем в вашем WebApiConfig выполните:

    config.Formatters.JsonFormatter.SerializerSettings.TraceWriter = new TraceWriter();

(возможно, оберните его в #if DEBUG)


Похоже, может быть много разных причин этой проблемы ...

Я обнаружил, что добавление обратного вызова OnDeserialized к классу модели приводило к тому, что параметр всегда был null . Точная причина неизвестна.

using System.Runtime.Serialization;

// Validate request
[OnDeserialized]  // TODO: Causes parameter to be null
public void DoAdditionalValidatation() {...}

Просто добавьте мою историю в эту тему. Моя модель:

public class UserProfileResource
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Phone { get; set; }

    public UserProfileResource()
    {
    }
}

не может быть сериализована в моем контроллере API, всегда возвращающая значение null. Проблема была в Id типа type Guid : каждый раз, когда я передавал пустую строку как Id (наивный, что он будет автоматически преобразован в Guid.Empty ) из моего интерфейса, я получил нулевой объект в качестве [FromBody] paramether.

Решение было

  • действующее значение Guid
  • или изменить Guid to String

У меня была эта проблема в моем веб-интерфейсе .NET Framework, потому что моя модель существовала в проекте .NET Standard, который ссылался на другую версию аннотаций данных.

Добавление строки ReadAsAsync ниже показало причину для меня:

public async Task<HttpResponseMessage> Register(RegistrationDetails registrationDetails)
{
    var regDetails = await Request.Content.ReadAsAsync<RegistrationDetails>();

Это немного старый, и мой ответ дойдет до последнего места, но даже я хотел бы поделиться своим опытом.

Пробовал каждое предложение, но все еще имел одно и то же «нулевое» значение в PUT [FromBody].

Наконец, выяснилось, что все это касается формата даты, а JSON - сериализации свойства EndDate моего Углового объекта.

Ошибка не была выбрана, просто получил пустой объект FromBody ....


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

Очевидно, что у вашей модели должен быть пустой / стандартный конструктор, иначе модель не может быть создана. Будьте осторожны при рефакторинге. ;)


Я также пытался использовать [FromBody], однако я пытался заполнить строковую переменную, потому что вход будет меняться, и мне просто нужно передать его вместе с бэкэнд-службой, но это всегда было нулевым

Post([FromBody]string Input]) 

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

Post(dynamic DynamicClass)
{
   string Input = JsonConvert.SerializeObject(DynamicClass);

Это хорошо работает.





asp.net-web-api