angular - 为什么 ASP.NET Core 不接受以纯文本形式发送 PUT 请求?

标签 angular asp.net-core httprequest

我正在尝试发送包含字符串的 PUT 请求。

请求从 Angular 中的客户端发送到作为 ASP.NET Core Controller 的服务器。请求 header 是 text/plain

要使 ASP.NET Core 接受 text/plain,我必须遵循 this教程,仅当我使用 Postman 发送请求时才有效:
当我尝试从客户端向服务器发送相同的请求时,它不起作用,请求未事件触发 RawRequestBodyFormatter 类的制动点。

Angular 服务:

export class LendedBookService {
  private baseUrl: string;

  constructor(private httpClient: HttpClient) {
    this.baseUrl = 'http://localhost:55152/';
  }

  public sendReminder(lendedBookId: string): Observable<any> {
    var headers = new HttpHeaders({'Content-Type': 'text/plain; charset=utf-8'});
    return this.httpClient.put<string>(this.baseUrl + 'api/lendedBook/sendReminder', lendedBookId, {
      headers: headers
    });
  }
}

ASP.NET 核心 Controller :

[Route("api/[controller]/[action]")]
[ApiController]
public class LendedBookController : ControllerBase
{
    private readonly Libranian libranian;

    public LendedBookController(Libranian libranian)
    {
        this.libranian = libranian;
    }

    [HttpPut]
    public async Task<IAsyncResult> SendReminder([FromBody]string lendedBookId)
    {
        using (var unitOfWork = UnitOfWorkLocator.GetUnitOfWork())
        {
            if (await libranian.NotifyToReturnLend(new Guid(lendedBookId)))
            {
                return Task.Run(() => NoContent());
            }

            return Task.Run(() => StatusCode(500));
        }
    }
}

在这种情况下发送 text/plain 请求我应该怎么做或者我做错了什么?
谢谢!

最佳答案

一个原因可能是:

跨源资源共享 (CORS) 是一种机制,它使用额外的 HTTP header 告诉浏览器让在一个源(域)运行的 Web 应用程序有权访问来自不同源的服务器的选定资源。当 Web 应用程序请求来源(域、协议(protocol)和端口)与其自身来源不同的资源时,它会执行跨域 HTTP 请求。

跨源请求的示例:从 http://domain-a.com 提供的网络应用程序的前端 JavaScript 代码使用 XMLHttpRequest 请求 http://api.domain-b.com/data.json .

出于安全原因,浏览器限制从脚本中发起的跨源 HTTP 请求。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一来源请求 HTTP 资源,除非来自其他来源的响应包含正确的 CORS header 。

ref

来到 .NET Core:.NET Core 是否支持 CORS? 是的,确实如此。

将 CORS 与 .NET Core 结合使用简单易行。

您只需按照以下步骤操作:

  • 安装 Microsoft.AspNetCore.Cors Nuget 包。
  • 在 ConfigureService 方法中配置 CORS。
  • 在 Configure 方法中使用中间件启用 CORS。
  • 通过在 Controller 或操作中启用 .NET Core MVC 中的 CORS 或全局。 ref

更新

没有 JSON - 没有 Workey 如果你想发送一个 RAW 字符串或二进制数据,并且你想把它作为你请求的一部分,事情就会变得更加复杂。 ASP.NET Core 只处理它知道的内容,默认情况下是 JSON 和表单数据。默认情况下,原始数据不能直接映射到 Controller 参数。

我基本上在做与第一个请求相同的事情,只是我发送的不是 JSON 内容类型而是纯文本。端点存在,但 MVC 不知道如何处理文本/纯内容或如何映射它,因此它失败并返回 404 Not Found。

这不是很明显,我知道这可能会误导希望映射原始内容的毫无戒心的新手。但是,如果您考虑一下,这是有道理的:MVC 具有特定内容类型的映射,如果您传递不适合这些内容类型的数据,它就无法转换数据,因此它假定没有匹配的端点可以处理请求。

那么我们如何获得原始数据呢?

读取原始数据的 Request.Body 不幸的是,ASP.NET Core 不允许您仅通过方法参数以任何有意义的方式捕获“原始”数据。无论采用何种方式,您都需要对 Request.Body 进行一些自定义处理以获取原始数据,然后将其反序列化。

您可以捕获原始 Request.Body 并从中读取原始缓冲区,这非常简单。

最简单、侵入性最小但不是很明显的方法是使用一种方法,该方法接受不带参数的 POST 或 PUT 数据,然后从 Request.Body 中读取原始数据:

[HttpPost]
[Route("api/BodyTypes/ReadStringDataManual")]
public async Task<string> ReadStringDataManual()
{
    using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
    {  
        return await reader.ReadToEndAsync();
    }
}

Check this post

关于angular - 为什么 ASP.NET Core 不接受以纯文本形式发送 PUT 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55879153/

相关文章:

dart - 如何在dart上发出HTTP请求并传递参数

javascript - 在 react 中发布请求

javascript - 访问 Angular 分量元数据

node.js - 用于 e2e 前端测试的暂存后端

asp.net-core - 在构建 WebHost 之前访问托管环境

c# - 如何在 ASP.NET Core 中手动生成防伪 token

sms - Twilio SMS 验证目标电话号码和验证 ID

Angular 6 如何将选中的复选框传递给 ngModel

html - 没有选择和选项标签的 Angular react 形式下拉列表

sql-server - 数据库优先 EF7-beta7 dnx ef dbcontext scaffold 命令失败