當用 Web API 的時候
.NET Core 會自動將 Post 的 Body 轉成字串或 Json
也可以用 Class 來接
不過因為是自動轉型
卻變成無法取得原始的 Post 參數
萬一預設是接受 Json
但對方傳 Text 過來
.NET Core 就自動回傳錯誤訊息
如果可以取得原始 Body
處理過後再傳給 API 
那就方便不過了

 

正常狀況,接收 Json 轉成 Class

錯誤狀況,無法轉成 Json,就不會進到 API 的程式

 


利用 RawRequestBodyFormatter 取得 Raw Body
經過處理後,再往後傳給 API
在 Startup.cs 加入設定

 

加入 RawRequestBodyFormatter.cs 

using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Formatters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace TodoApi
{
    public class RawRequestBodyFormatter : IInputFormatter
    {
        public bool CanRead(InputFormatterContext context)
        {
            if (context == null) throw new ArgumentNullException("argument is Null");
            var contentType = context.HttpContext.Request.ContentType;

            if (contentType == "text/plain" || contentType == "application/json")
                return true;

            return false;
        }

        public async Task ReadAsync(InputFormatterContext context)
        {
            var request = context.HttpContext.Request;
            var contentType = context.HttpContext.Request.ContentType;

            if (string.IsNullOrEmpty(contentType) || contentType.ToLower() == "text/plain")
            {
                using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8))
                {
                    var content = await reader.ReadToEndAsync();

                    return await InputFormatterResult.FailureAsync();
                }
            }

            if (string.IsNullOrEmpty(contentType) || contentType.ToLower() == "application/json")
            {
                using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8))
                {
                    var content = await reader.ReadToEndAsync();

                    if (string.IsNullOrEmpty(content)) return await InputFormatterResult.FailureAsync();

                    var obj = JObject.Parse(content);
                    User user = new User();
                    user.Id = int.Parse(obj["Id"].ToString());
                    user.Name = "U_" + obj["name"].ToString();

                    return await InputFormatterResult.SuccessAsync(user);
                }
            }

            return await InputFormatterResult.FailureAsync();
        }
    }
}

就可以對原始資料就處理了,上面是把 name 加上 U_ 開頭

 


參考資料:
Accepting Raw Request Body Content in ASP.NET Core API Controllers
Asp.Net Core控制器如何接收原始請求正文內容詳解