Самый простой способ POST 2 строки без создания модели

У меня есть объект, который я пытаюсь опубликовать в своем API С#, который состоит всего из двух строк:

Body Пример:

fetch(url, {
  method: 'POST',
  body: { username: 'myusername', password: 'mypassword' },
  headers:{
    'Content-Type': 'application/json'
  }
});

Мой метод API выглядит так:

[HttpPost("auth")]
public async Task<IActionResult>(NetworkCredential creds) { ... }

Но я хочу, чтобы это было так:

[HttpPost("auth")]
public async Task<IActionResult>(string username, string password) { ... }

Я действительно не хочу создавать модель только для двух строк (именно поэтому я сейчас использую NetworkCredential). У меня есть другие случаи, когда это не имя пользователя и пароль, поэтому я не могу обойтись без использования NetworkCredential во всех случаях.

Есть ли какая-нибудь волшебная комбинация/способ настройки метода API для извлечения отдельных строк из полезной нагрузки без необходимости создания модели с двумя свойствами? Я поиграл с некоторыми атрибутами (например, [FromBody]), но безуспешно.

Поделитесь, пожалуйста, как вы POST делаете свой объект. Оба фрагмента должны работать независимо от того, разделяете ли вы параметры или используете модель.

Tyler Roper 23.07.2019 20:06

Это просто HttpPost из javascript. На самом деле я использую модуль Angular HttpClient на практике, но играю с почтальоном для более быстрой разработки.

mwilson 23.07.2019 20:08

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

user47589 23.07.2019 20:10

рассмотрите возможность использования тела формы.

Daniel A. White 23.07.2019 20:10

@amy Меня не волнует проверка на уровне модели. Я совершенно не против делать простые null проверки двух строк. Мой вариант использования довольно прост (поэтому мне не нужны модели для всех моих «конечных точек с двумя строками»,

mwilson 23.07.2019 20:11

IIRC для передачи нескольких простых значений используйте данные формы вместо JSON, как предложил @DanielA.White. К сожалению, я не знаю, как это сделать с помощью fetch.

user47589 23.07.2019 20:15

@mwilson Вы можете написать метод расширения в JavaScript, чтобы превратить ваш объект в строку запроса, соответствующую типу контента form-urlencoded по умолчанию (так же, как это делает jQuery в своем $.ajax's data option / $.param методе).

Tyler Roper 23.07.2019 20:15

Я попробую данные формы.

mwilson 23.07.2019 20:18

@mwilson Проверьте это: angular — запрос POST HttpClient с использованием x-www-form-urlencoded

Tyler Roper 23.07.2019 20:19

Просто отправка объекта FormData работает как шарм. Всем спасибо.

mwilson 23.07.2019 20:21
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
10
92
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы не можете сделать это с помощью контроллера веб-API, поскольку javascript не может вызывать метод, если не передан объект.

Однако есть «технические» (2) способы сделать это без создания классов моделей в вашем проекте .NET.

  1. Передать FormDataCollection объект

    public async Task<IActionResult> YourMethod(FormDataCollection form) { var whatever = form.Get("username"); var whatever2 = form.Get("password"); }

Вам, конечно, придется настроить вызов ajax для передачи объекта коллекции форм.

  1. Пройти JObject (динамический JSON).

Для этого вам понадобится библиотека Newtonsoft.JSON.

public async Task<IActionResult> YourMethod(JObject json)
{
    dynamic jsonObj = json;
    var whatever = jsonObj.username;
    var whatever2 = jsonObj.password;
}

Возможно, вам придется добавить атрибут [FromBody] перед JObject (я забыл). Кроме того, вы можете использовать dynamic вместо JObject

(то есть - YourMethod(dynamic json) {....}

Ты сможешь. Как указано в моих комментариях, просто передача полезной нагрузки как FormData (в отличие от json) делает свое дело.

mwilson 23.07.2019 21:26

Вы уже пробовали использовать dynamic или JObject? А я твои комментарии не читал, только ОП. Спасибо за -1, хотя ;)

Rob Scott 23.07.2019 21:29

Использование JObject вместе с dynamic — это не то, о чем просили. Я привел пример настройки метода, который хотел. Ваш ответ противоположен тому, к чему я стремился, и не внес никакого полезного вклада.

mwilson 23.07.2019 21:34
Ответ принят как подходящий

Спасибо @Daniel A. White и @Amy за направление.

Мое решение состояло в том, чтобы передавать данные как FormData, а не json от клиента. Выполнение этого таким образом позволяет моему «разыскиваемому» методу работать.

ПРИМЕЧАНИЕ:this._httpClient из Угловой модуль HttpClient

Пример:

const formData = new FormData();
formData.append('username', 'myusername');
formData.append('password', 'mypassword');
const response = await this._httpClient.post(<url>, formData).toPromise();

Метод API:

[HttpPost("auth")]
public async Task<IActionResult>(string username, string password) { ... }

Вы можете делать то, что вы описываете, с вашей текущей настройкой. На самом деле, это должно сработать, если вы оставите это почти так, как в своем вопросе.

Конечная точка веб-API:

[HttpPost("auth")]
public async Task<IActionResult> Authenticate(string username, string password) { ... }

Сообщение от JS:

fetch(url, {
  method: 'POST',
  body: { username: 'myusername', password: 'mypassword' },
  headers:{
    'Content-Type': 'application/json'
  }
});

Привязка по умолчанию в веб-API попытается сопоставить свойства из body выше по имени с 1) отдельными параметрами действия или 2) если имена не совпадают и есть объект модели, то со свойствами этого объект.

В приведенном выше случае он должен сопоставляться с двумя отдельными параметрами.

Однако обычно считается хорошей практикой заключать отдельные параметры в модель. Если вы решите сделать это в будущем, ниже приведен пример:

class MyModel {
    public string UserName {get;set;}
    public string Password {get;set;}
}

и конечная точка будет выглядеть так:

[HttpPost("auth")]
public async Task<IActionResult> Authenticate(MyModel model) { ... }

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

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

mwilson 23.07.2019 22:38

Если вы не изменили настройки веб-API по умолчанию, поддержка JSON должна быть включена. Это больше похоже на проблему отладки. Я бы проверил пару вещей: 1) присутствуют ли правильные данные в запросе, когда вы получаете его в веб-API? 2) правильно ли десериализованы данные? Для (1) поставьте точку останова в действии и посмотрите на this.Request? Для (2), если this.Request содержит ожидаемые данные, убедитесь, что вы где-то не удаляете поддержку JSON (аналогично этому): stackoverflow.com/questions/10250098/…

Daniel Gabriel 23.07.2019 23:18

Это определенно возможно. Происходят некоторые пользовательские вещи (большое приложение), поэтому я не сомневаюсь, что кто-то где-то испортил настройки веб-API.

mwilson 23.07.2019 23:20

Другие вопросы по теме