. Net Core 3.0 Angular параметр пост-запроса приложения всегда равен NULL - PullRequest
0 голосов
/ 09 мая 2020

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

Итак, я создал проект. Net Core 3.0 Angular в Visual Studio и создал меню выбора, которое при изменении отправляет запрос POST с выбранным значением, однако на контроллере полученный POST всегда NULL

Это мой HTML

<select class="form-control" (change)="languageChanged($event.target.value)">
  <option *ngFor="let language of languages | keyvalue:returnZero" value="{{language.key}}">{{language.value}}</option>
</select>

Для запроса POST на стороне клиента я пробовал два следующих подхода:

    this.http.post("Language", lang).subscribe(result => {
  console.log(result);
}, error => console.error(error));

и

this.http.post<LanguageInterface>("Language", lan).subscribe(result => {
  console.log(result);
}, error => console.error(error));

где

export interface LanguageInterface { language: string; }

На стороне сервера

public class Language
{
  public string language { get; set; } 
}

в HTTP-сообщении я также пробовал две вещи

public IActionResult Post(Language lan)
{
  // logic
  return Ok();
}

и я попытался изменить метод на

public async Task<IActionResult> Post([FromForm]Language lan)

Любая помощь будет принята с благодарностью! Спасибо за уделенное время!

Ответы [ 2 ]

1 голос
/ 09 мая 2020

В вашем сообщении есть несколько разных вопросов, на которые я был бы рад ответить для вас:

Почему язык не заполняется в вашем методе контроллера?

Вы указываете, что метод на вашем контроллере API выглядит так:

public IActionResult Post(Language lan)
{
  // logic
  return Ok();
}

Вы не указываете, настраиваете ли вы конечные точки в своей настройке, поэтому я предполагаю, что нет. Вы должны обновить это с помощью, чтобы вместо этого выглядеть следующим образом. Это сделает две вещи: 1) первая строка проинформирует ASP. NET Core, что этот метод должен соответствовать запросу POST с указанным шаблоном, и 2) атрибут [FromBody] в аргументе сообщает ASP. NET Ядро, из которого следует заполнить значение (тело POST).

[HttpPost("Language")] //Handles a call to /language as you attempt in both your first and second calls from Angular.
public IActionResult Post([FromBody]Language lan)
{
  //logic
  return Ok();
}

Если вы используете async и Task<T> в последнем образце контроллера

Если вы не выполняете асинхронные действия в вашем комментарии //logic, нет причин украшать метод async или возвращать Task<IActionResult>. Приведенного выше примера более чем достаточно.

Заполняете ли вы какие-либо данные для отправки?

Это стоило бы взглянуть на ваш сетевой запрос для проверки, но если вы не выполняете сопоставление в вашем компоненте Angular вы устанавливаете значение поля option на "language.key", но при вызове this.http.post вы передаете lang, а затем lan, которые иным образом не используются в вашем примере кода. Таким образом, я не могу подробно разбираться в том, что там может происходить, но, возможно, стоит открыть ваши сетевые инструменты в вашем браузере и подтвердить, что запрос POST на ваш сервер действительно заполняется предполагаемыми данными из Angular компонент.

Возможно, вы неправильно понимаете синтаксис TypeScript на стороне Angular при обращении к this.http.post

. Вы указываете, что пытаетесь отправить данные с помощью:

this.http.post<LanguageInterface>("Language", lan).subscribe(result => {
  console.log(result);
}, error => console.error(error));

Мое беспокойство здесь просто проистекает из этого второго примера, который вы даете, учитывая, что вы передаете данные из LanguageInterface, предположительно в параметр lan, но вы также ссылаетесь на это в this.http.post<LanguageInterface>. Использование <> в методе заключается в том, чтобы ввести ответ, который вы ожидаете от вызова, и здесь не используется должным образом. Скорее, поскольку ваши методы контроллера в ASP. NET Core просто возвращают Ok() ActionResult, ожидаемого типа для ответа нет, поэтому здесь это не имеет особого смысла.

В этом случае ваш первый пост-вызов от Angular использует правильный синтаксис:

this.http.post("Language", lang).subscribe(result => {
  console.log(result);
}, error => console.error(error));

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

Заключение

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

В вашем Angular компоненте

this.http.post("Language", lang).subscribe(result => {
  console.log(result);
}, error => console.error(error));

Ваш ASP . NET Метод основного контроллера

[HttpPost("Language")] //Handles a call to /language as you attempt in both your first and second calls from Angular.
public IActionResult Post([FromBody]Language lan)
{
  //logic
  return Ok();
}

Почему [HttpPost("Language")] нарушает это?

Вы изначально не указали подпись контроллера в своем вопросе, поэтому раньше это не было очевидно . Поскольку ваш атрибут [Route] на контроллере установлен как [Route("[controller]")], он использует соглашение ASP. NET Core для использования имени контроллера перед «Controller» - в вашем случае ваш класс - «LanguageController. ", поэтому любой запрос к / Language будет указывать здесь как допустимый параметр.

Поскольку я тогда предложил маршрут на [HttpPost("Language")], это дополнительно добавляет шаблон, необходимый для сопоставления. Если вы отправили запрос POST на localhost:<port>/Language/Language, вы увидите, что он соответствует методу, как и ожидалось.

Чтобы исправить это, просто измените атрибут в методе на [HttpPost] и исключите аргумент шаблона будет означать, что это будет соответствовать вызову localhost:<port>/Language, если это единственный метод POST с этой подписью в контроллере.

0 голосов
/ 09 мая 2020

Итак, с полезным ответом Ксаниффа и некоторым чтением мне удалось заставить его работать! Я сделал следующие изменения

В компоненте angular:

let post: LanguageInterface = {
  language: this.currentLanguage,
}
this.http.post("Language", post).subscribe(result => {
  console.log(result);
  this.data.changeLanguage(this.currentLanguage);
  this.toastr.success("Ok");
 }, error => console.error(error));

Я использую созданный мной интерфейс для установки полученного значения и отправки его в контроллер. Код контроллера. :

[ApiController]
[Route("[controller]")]
public class LanguageController : Controller
{

    [HttpPost]
    public IActionResult Post([FromBody]Language lan)
    {
        // logic
        return Ok();
    }

}

Даже подумав, что это работает, я был бы признателен за ответ, почему "[HttpPost (" Language ")]" делает его сломанным.

С уважением, С уважением!

...