У меня есть объект, который я пытаюсь опубликовать в своем 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]), но безуспешно.
Это просто HttpPost из javascript. На самом деле я использую модуль Angular HttpClient на практике, но играю с почтальоном для более быстрой разработки.
Наличие модели позволяет вам применять атрибуты проверки, чего я не думать вы можете сделать с парой строковых параметров.
рассмотрите возможность использования тела формы.
@amy Меня не волнует проверка на уровне модели. Я совершенно не против делать простые null проверки двух строк. Мой вариант использования довольно прост (поэтому мне не нужны модели для всех моих «конечных точек с двумя строками»,
IIRC для передачи нескольких простых значений используйте данные формы вместо JSON, как предложил @DanielA.White. К сожалению, я не знаю, как это сделать с помощью fetch.
@mwilson Вы можете написать метод расширения в JavaScript, чтобы превратить ваш объект в строку запроса, соответствующую типу контента form-urlencoded по умолчанию (так же, как это делает jQuery в своем $.ajax's data option / $.param методе).
Я попробую данные формы.
@mwilson Проверьте это: angular — запрос POST HttpClient с использованием x-www-form-urlencoded
Просто отправка объекта FormData работает как шарм. Всем спасибо.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы не можете сделать это с помощью контроллера веб-API, поскольку javascript не может вызывать метод, если не передан объект.
Однако есть «технические» (2) способы сделать это без создания классов моделей в вашем проекте .NET.
Передать FormDataCollection объект
public async Task<IActionResult> YourMethod(FormDataCollection form)
{
var whatever = form.Get("username");
var whatever2 = form.Get("password");
}
Вам, конечно, придется настроить вызов ajax для передачи объекта коллекции форм.
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) делает свое дело.
Вы уже пробовали использовать dynamic или JObject? А я твои комментарии не читал, только ОП. Спасибо за -1, хотя ;)
Использование JObject вместе с dynamic — это не то, о чем просили. Я привел пример настройки метода, который хотел. Ваш ответ противоположен тому, к чему я стремился, и не внес никакого полезного вклада.
Спасибо @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 оказались нулевыми.
Если вы не изменили настройки веб-API по умолчанию, поддержка JSON должна быть включена. Это больше похоже на проблему отладки. Я бы проверил пару вещей: 1) присутствуют ли правильные данные в запросе, когда вы получаете его в веб-API? 2) правильно ли десериализованы данные? Для (1) поставьте точку останова в действии и посмотрите на this.Request? Для (2), если this.Request содержит ожидаемые данные, убедитесь, что вы где-то не удаляете поддержку JSON (аналогично этому): stackoverflow.com/questions/10250098/…
Это определенно возможно. Происходят некоторые пользовательские вещи (большое приложение), поэтому я не сомневаюсь, что кто-то где-то испортил настройки веб-API.
Поделитесь, пожалуйста, как вы
POSTделаете свой объект. Оба фрагмента должны работать независимо от того, разделяете ли вы параметры или используете модель.