После обновления до RC для WebAPI у меня возникла странная проблема при вызове POST в моем WebAPI. Я даже вернулся к базовой версии, созданной для нового проекта. Так:
public void Post(string value)
{
}
и звонит из Fiddler:
Header:
User-Agent: Fiddler
Host: localhost:60725
Content-Type: application/json
Content-Length: 29
Body:
{
"value": "test"
}
Когда я отлаживаю, строка «значение» никогда не присваивается. Просто всегда NULL. У кого-нибудь есть эта проблема?
(Я впервые увидел проблему с более сложным типом)
Проблема связана не только с ASP.NET MVC 4, такая же проблема возникает для нового проекта ASP.NET MVC 3 после установки RC
c#
.net
asp.net-web-api
asp.net-web-api-routing
ianrathbone
источник
источник
Ответы:
Поскольку у вас есть только один параметр, вы можете попытаться украсить его
[FromBody]
атрибутом или изменить метод, чтобы он принимал DTO со значением в качестве свойства, как я предложил здесь: MVC4 RC Привязка параметров WebApiОБНОВЛЕНИЕ: Официальный сайт ASP.NET был обновлен сегодня с отличным объяснением: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part- 1
В двух словах, при отправке одного простого типа в теле, отправьте только значение с префиксом знака равенства (=), например, body:
=test
источник
=
никогда не работало для меня, пока я не последовал совету Джима в его комментарии (не как объект JSON), и это сработало. Это ключ! Мне действительно не нравится, насколько требователен WebAPI.:(
). Вы действительно должны добавить поддержку того формата, в котором люди ожидают его принятия.Я почесал голову над этим сегодня.
Мое решение изменить
[FromBody]
кHttpRequestMessage
, по существу , двигаясь вверх по HTTP стека.В моем случае я посылаю данные по проводу, который является zips json, который затем base64'd. Все это из приложения для Android.
Оригинальная подпись моей веб-конечной точки выглядела так (используя
[FromBody]
):Мое исправление для этой проблемы состояло в том, чтобы вернуться к использованию
HttpRequestMessage
для подписи моей конечной точки.Затем вы можете получить доступ к данным поста, используя следующую строку кода:
Это работает и позволяет вам получить доступ к необработанным нетронутым данным поста. Вам не нужно возиться с Fiddler, помещающим знак = в начале вашей строки или изменяющим тип контента.
Кроме того, я сначала попытался следовать одному из приведенных выше ответов, который состоял в том, чтобы изменить тип содержимого на «Content-Type: application / x-www-form-urlencoded». Для необработанных данных это плохой совет, потому что он убирает символы +.
Итак, строка base64, которая начинается примерно так: «MQ0AAB + LCAAAAAA» заканчивается так: «MQ0AAB LCAAAAAA»! Не то, что вы хотите.
Еще одним преимуществом использования
HttpRequestMessage
является то, что вы получаете доступ ко всем заголовкам http из вашей конечной точки.источник
HttpRequestMessage request
в сигнатуре метода, как у вас всегда это уже есть. В теле метода можно получить доступ кRequest
объекту. напр.Request.Content.ReadAsStringAsync().Result;
Я только что это произошло, используя Fiddler. Проблема была в том, что я не уточнил
Content-Type
.Попробуйте включить заголовок для
Content-Type
в вашем запросе POST.В качестве альтернативы, согласно комментариям ниже, вам может понадобиться включить заголовок JSON
источник
contentType: "application/x-www-form-urlencoded; charset=UTF-8"
, для полного примера см. Complete Cient и ServerЯ столкнулся с этой проблемой, и именно так я решил свою проблему
код вебапи:
код клиента:
источник
some value
, тоdata
это ноль.Я использовал,
Postman
и я делал ту же ошибку .. передаваяvalue
объект как JSON вместо строкиЯсно, что вышеприведенное неверно, когда параметр api имеет тип string.
Итак, просто передайте строку в двойных кавычках в теле API:
источник
JSON.stringify
заставляет меня[frombody]
бытьnull
. После установки в поле данных строкового значения (то есть строки json) это сработало.Попробуйте создать класс, который будет служить моделью данных, а затем отправьте объект JSON со свойствами, соответствующими свойствам вашего класса модели данных. (Примечание: я проверил это, и оно работает с новейшей MVC 4 RC 2012, которую я только что скачал сегодня).
Приведенный ниже объект JSON отправляется в теле HTTP-POST, тип содержимого - application / json
Я считаю, что причина, по которой вы должны создать класс модели данных, заключается в том, что простые значения предполагаются из параметров url, а одно комплексное значение предполагается из тела. Они имеют
[FromBody]
и[FromUrl]
атрибуты, но с использованием до[FromBody] string value
сих пор не работает для меня. Похоже, что они до сих пор исправляют множество ошибок, поэтому я уверен, что это изменится в будущем.Изменить: Получил XML для работы в теле. Сериализатор XML по умолчанию был изменен на DataContractSerializer вместо XmlSerializer. Помещение следующей строки в мой файл Global.asax устранило эту проблему ( ссылка )
источник
После некоторых попыток я думаю, что поведение по умолчанию правильное и взломать нечего.
Единственная хитрость: если ваш аргумент метода post
string
подобен приведенному ниже, вы должны отправить обычную строку с двойными кавычками в теле (при использовании ajax или почтальона), например,В противном случае, если вы отправляете строку json в теле сообщения без внешних двойных кавычек и экранированных внутренних кавычек, то она должна быть в состоянии проанализировать класс модели (тип аргумента), например,
{"a":1, "b":2}
источник
Я искал решение этой проблемы уже несколько минут, поэтому поделюсь своим решением.
Если вы публикуете модель, ваша модель должна иметь пустой конструктор / конструктор по умолчанию, иначе модель не может быть создана, очевидно. Будьте осторожны при рефакторинге. ;)
источник
Это сработало для меня:
Создайте класс C # DTO со свойством для каждого атрибута, который вы хотите передать из jQuery / Ajax
Определите метод веб-API:
Назовите веб-API так:
источник
Для тех, у кого такая же проблема с Swagger или Postman, как у меня, если вы передаете простой атрибут в виде строки в сообщении, даже с указанным «ContentType», вы все равно получите нулевое значение.
Проходя просто:
MyValue
Попадет в контроллер как ноль.
Но если вы пройдете:
"MyValue"
Значение станет правильным.
Цитаты сделали разницу здесь. Конечно, это только для Сваггера и Почтальона. Например, в приложении Frontend, использующем Angular, это должно решаться платформой автоматически.
источник
У меня была та же проблема, и я обнаружил, что при изменении типа контента на «application / json» проблема не устраняется. Однако "application / json; charset = utf-8" сработало.
источник
У меня была похожая проблема, когда объект запроса для моего метода Web API всегда был нулевым. Я заметил, что, поскольку в имени действия контроллера был указан префикс «Get», Web API воспринимал это как HTTP GET, а не как POST. После переименования действия контроллера оно теперь работает как задумано.
источник
С Angular я смог передать данные в этом формате:
А в Web API Controler:
В качестве альтернативы я также мог бы опубликовать данные в формате JSON следующим образом:
И в контроллере примите тип класса, подобный этому:
В любом случае, если у вас есть общедоступный класс в API, отправьте JSON, в противном случае отправьте '=' + JSON.stringify ({..: ..., ..: ...})
источник
В моем случае проблема заключалась в том, что параметр был строкой, а не объектом, я изменил параметр на JObject of Newsoft.Json, и он работает.
источник
Добавление строки
до конца функции
protected void Application_Start()
в Global.asax.cs исправлена аналогичная проблема для меня в ASP.NET MVC3.источник
Если вы используете DataContractSerializer для вашего Xml Formatter или JSON Formatter, вам нужно избавиться от него. У меня было это в моем файле WebApiConfig:
Просто я комментирую,
jsonFormatter.UseDataContractJsonSerializer = true;
и мой входной параметр больше не является нулевым. Спасибо «Despertar» за подсказку.источник
Если вы уверены в своем отправленном JSON, вы должны тщательно отслеживать свой API:
Microsoft.AspNet.WebApi.Tracing
пакетconfig.EnableSystemDiagnosticsTracing();
в методWebApiConfig
внутри классаRegister
.Теперь посмотрите на вывод отладки, и вы, вероятно, найдете недействительный
ModelState
запись в журнале.Если
ModelState
недействителен, вы можете найти реальную причину в егоErrors
:Никто не может даже догадываться о таком исключении:
источник
У меня была такая же проблема получения нулевого значения, как у параметра, но это было связано с большими объектами. Оказалось, что проблема связана с максимальной длиной IIS. Это можно настроить в web.config.
Интересно, почему Web API подавил ошибку и отправляет нулевые объекты моим API. Я нашел ошибку с помощью Microsoft.AspNet.WebApi.Tracing.
источник
JSON.stringify (...) решил мои проблемы
источник
Я знаю, что это не ответ на этот вопрос, но я столкнулся с ним при поиске решения моей проблемы.
В моем случае сложный тип не был связан, но я не делал POST, я делал GET с параметрами строки запроса. Решением было добавить [FromUri] в arg:
источник
У меня была такая же проблема в Fiddler. Я уже имел
Content-Type: application/json; charset=utf-8
илиContent-Type: application/json
в заголовке запроса.Мой запрос тело было также простая строка, а в Fiddler я написал:
{'controller':'ctrl'}
. Это сделало строковый параметр в моем методе POSTnull
.Исправление : не забудьте использовать кавычки, тем самым указав строку. То есть я исправил это письменно
"{'controller':'ctrl'}"
. (Примечание: при написании JSON обязательно используйте апострофы или экранируйте кавычки следующим образом:)"{\"controller\":\"ctrl\"}"
.источник
Самый простой способ, который я нашел для работы с простым JSON-объектом, который я передаю в MVC 6, - это получить тип параметра post, такой как NewtonSoft jObject:
источник
[FromBody] object body, [FromHeader(Name="Content-Type")] string bodyMediaType
) может работать лучше, так как проверкаbodyMediaType == "application.json"
перед приведением тела к JObject предоставляет возможность для альтернатив.Лучшее решение для меня - полный HTTP, как показано ниже:
и затем десериализацию строки в объект, который вы ожидаете в теле сообщения. Для меня WS_OpenSession - это класс, который содержит sessionid, user и key.
Оттуда вы можете использовать объект param и получить доступ к его свойствам.
Очень очень эффективно.
Я сказал источник из этого URL:
http://bizcoder.com/posting-raw-json-to-web-api
источник
Для сложных типов Web API пытается прочитать значение из тела сообщения, используя средство форматирования медиа-типа.
Пожалуйста, проверьте, есть ли у вас
[Serializable]
атрибут, украшающий ваш класс модели.Удалите атрибут, чтобы увидеть, работает ли он. Это сработало для меня.
источник
Я немного опоздал на вечеринку, но любой, кто сталкивается с пропущенным значением NULL при использовании контроллера, просто добавляет «=» в начало вашего запроса POST.
Контроллер также передал значение NULL, когда я использовал тип содержимого application / json . Обратите внимание на тип содержимого application / x-www-form-urlencoded ниже. Тип возврата из API, однако, является «application / json».
источник
не имеет значения, какой тип значения вы хотите опубликовать, просто заключите его в кавычки, чтобы получить его в виде строки. Не для сложных типов.
JavaScript:
C #:
источник
Если вы добавили аннотацию [FromBody] и у вас есть объект Dto в качестве параметра для вашего метода, но вы все еще не можете получить данные, начните изучать свойства и поля вашего DTO.
У меня была такая же проблема, когда мой DTO обнулялся. Я обнаружил, что причина была в том, что одно из свойств указывало на объект, который не может быть сериализован :(, что приводит к тому, что медиа-форматер не может анализировать данные. Таким образом, объект всегда был нулевым. Надеюсь, что это также помогает другим
источник
Дважды проверьте ваши типы данных. Связыватель модели dotnet не будет преобразовывать число с плавающей точкой в целое число (и я предполагаю другие связанные понятия). Это приведет к отклонению всей модели.
Если у вас есть JSON, как это:
но ваша модель c # выглядит так:
связыватель модели отклонит модель, и вы получите ноль.
источник
Я довольно поздно опоздал, но у меня возникли похожие проблемы, и после дня, проведенного здесь после получения множества ответов, я нашел самое простое / легкое решение для передачи одного или нескольких параметров в Web API 2. следующим образом:
Это предполагает, что вы знаете, как настроить контроллер / действие Web API с правильной маршрутизацией, если не обратитесь к: https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with -aspnet-web-api / tutorial-your-first-web-api .
Во-первых, действие контроллера, для этого решения также требуется библиотека Newtonsoft.Json.
Клиентская сторона, использующая jQuery
Ключевой проблемой, которую я обнаружил, было убедиться, что вы отправляете только один общий параметр обратно в Web API и убедитесь, что у него нет имени, только значение,
{ '': dataToSend }
иначе ваше значение будет нулевым на стороне сервера.При этом вы можете отправить один или несколько параметров в Web API в структуре JSON, и вам не нужно объявлять какие-либо дополнительные объекты на стороне сервера для обработки сложных данных. JObject также позволяет вам динамически перебирать все передаваемые параметры, обеспечивая более легкую масштабируемость, если ваши параметры изменяются со временем. Надеюсь, это поможет кому-то, кто боролся, как я.
источник
Корректная передача одного параметра в теле в WebAPI работает этот код
$.post(url, { '': productId }
И ловить это в действии
[HttpPost] public ShoppingCartAddRemoveViewModel Delete([FromBody]string value)
Ключ должен использовать волшебное слово «значение». Это может быть также int или некоторый примитивный тип. Независимо от типа содержимого или исправлений заголовка Беспорядок в том, что этот код не работает в пост-действии mvc.
источник