.Net Core 3.0 Angular application post 请求参数始终为NULL

.Net Core 3.0 Angular application post request parameter is always NULL

我想指出,这是我的第一个 .Net Core Angular 项目,如果问题看起来很明显,我深表歉意,我查看了类似的问题,但我的问题仍然存在,所以我想我正在做出了点问题。

所以我在 Visual Studio 中创建了一个 .Net Core 3.0 Angular 项目并创建了一个 select 菜单,该菜单在更改时发送一个 POST 请求 selected 值,但是在控制器上收到的 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 上 post 我也尝试了两件事

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

并且我尝试将方法更改为

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

如有任何帮助,我们将不胜感激! 感谢您的宝贵时间!

您 post 中有几个不同的问题,我很乐意为您解决:

为什么你的控制器方法中没有填充语言?

您指出 API 控制器上的方法如下所示:

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

您没有说明您是否在设置中配置端点,所以我假设没有。您应该将其更新为如下所示。这将做两件事:1)第一行将通知 ASP.NET 核心,此方法应将 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();
}

您是否应该在上一个控制器示例中使用 asyncTask<T>

除非您在 //logic 评论中执行异步活动,否则没有理由用 async 修饰方法或将其 return 变成 Task<IActionResult>。上面的例子已经足够了。

您是否正在填充任何要发送的数据?

这值得一看你的网络请求来验证,但除非你在你的 Angular 组件中做一些映射,否则你将选项字段的值设置为“language.key”,但在调用 this.http.post 时,您传入了 lang 并随后传入了 lan,这两者都没有在您的示例代码中使用。因此,我无法深入了解那里可能发生的事情,但值得在浏览器中打开网络工具并确认对服务器的 POST 请求实际上填充了来自的预期数据Angular 组件。

您可能在调用 this.http.post

时误解了 Angular 端的 TypeScript 语法

您表示您正在尝试发送数据:

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

我的担心仅来自您给出的第二个示例,假设您从 LanguageInterface 传递数据,可能以某种方式传递到 lan 参数,但您也在this.http.post<LanguageInterface>。在该方法上使用 <> 是为了键入您期望从调用中获得的响应,此处未正确使用。相反,因为 ASP.NET Core 中的控制器方法都只是 return 和 Ok() ActionResult,没有预期的响应类型,所以这在这里没有多大意义。

在这种情况下,来自 Angular 的第一个 post 调用使用了正确的语法:

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 核心约定在“控制器”之前使用控制器的名称 - 在您的情况下,您的 class 是“LanguageController”,因此对 /Language 的任何请求最终都会指向此处作为有效选项。

因为我随后在 [HttpPost("Language")] 上建议了一条路线,这进一步增加了匹配所需的模式。如果您向 localhost:<port>/Language/Language 发送 POST 请求,您会看到它与预期的方法匹配。

为了解决这个问题,只需将方法的属性更改为 [HttpPost] 并删除模板参数就意味着这将匹配对 localhost:<port>/Language 的调用,假设这是唯一的 POST 控制器中具有此签名的方法。

因此,在 Xaniff 的有用回答和一些阅读资料的帮助下,我成功地让它开始工作了! 我做了以下更改

在 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")]”会导致它损坏。

此致,此致!