ASP.NET Core 中从 ActionExecutionContext 的 HttpContext 获取 RawBody

cit*_*nas 5 c# asp.net-web-api asp.net-core asp.net-core-3.1

我有一个基类,我想在其中包含在所有控制器方法中执行的代码。在我的特殊情况下,我选择创建一个基类,覆盖OnActionExecution,并让我的控制器类从该基类继承。这非常有效:

public class BaseController : Controller
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        string parsedParameters = string.Empty;
        if (context.ActionArguments.Count > 0)
        {
            inputParameters = JsonConvert.SerializeObject(context.ActionArguments.First().Value,
                                    Formatting.None,
                                    new JsonSerializerSettings
                                    {
                                        NullValueHandling = NullValueHandling.Ignore,
                                    });
        }

        // ...

        base.OnActionExecuting(context);
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码从控制器方法获取映射的视图模型并将其转换为 JSON(用于日志记录目的)

控制器方法示例:

public async Task<IActionResult> Create([FromBody]CreateGroupRequest requestModel)
Run Code Online (Sandbox Code Playgroud)

我当前面临的问题是,已传递到端点的附加 json 值不包含在内,因为它们不会被映射(因为视图模型中不存在此类目标属性)

我想访问Request对象的原始主体。根据我所读到的内容,如果已经读取过一次请求正文流,则很难访问它。我找到了有关如何读取请求正文流的多种解决方案,但它们似乎仅适用于 .NET Framework 而不是 .NET Core。

问题ActionExecutinContext:如何从ASP.NET Core 中获取完整的请求正文(其中包括针对控制器发布的原始 JSON) ?

Nan*_* Yu 5

您可以使用 .net core 3.x 中的 EnableBuffering() 来启用请求正文以进行多次读取:

var bodyStr = "";
var req = context.HttpContext.Request;
req.EnableBuffering();
req.Body.Position = 0;
using (var stream = new StreamReader(req.Body))
{
    bodyStr = stream.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)