You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ABP应用服务的Post方法中获取请求体?

在ABP应用服务中实现接收请求体的Post方法

问题描述

需要创建包含Post方法的ABP应用服务,业务逻辑需获取请求体进行处理,已附上一个Controller示例代码,但查阅相关文档未找到解决方法。

原Controller示例代码

public class MedistatWebHookController : ControllerBase
{
    private readonly ILogger<MedistatWebHookController> _logger;

    public MedistatWebHookController(ILogger<MedistatWebHookController> logger)
    {
        _logger = logger;
        _logger.LogInformation(string.Format("Service Has Started {0}", DateTime.Now.ToString("dd MMM yyyy")));
    }

    [HttpPost]
    [Route("Events")]
    public async Task<IActionResult> ReceiveEvents()
    {
        try
        {
            _logger.LogInformation(string.Format("Start logging email post request from events {0}", DateTime.Now.ToString("dd MMM yyyy")));

            _logger.LogInformation(string.Format("Request Body {0}", Request.Body));

            var parser = new WebhookParser();
            var events = await parser.ParseEventsWebhookAsync(Request.Body).ConfigureAwait(false);

            foreach(var emailEvent in events)
            {
                var dump = ObjectDumper.Dump(emailEvent);
                string createText = dump;
                System.IO.File.WriteAllText(@"C:\Medistat\Logs\EmailEvents.txt", createText);
            }

            return Ok(); 
        }
        catch (Exception ex) 
        { 
            return BadRequest(ex.Message);
        }
    }
}

实现方案

ABP应用服务完全支持接收并处理请求体,以下是两种常用实现方式:

方式一:使用DTO绑定请求体(推荐)

如果请求体结构固定,定义对应DTO类,ABP会自动将请求体序列化到DTO参数中:

  1. 定义请求DTO:
public class WebhookEventRequestDto
{
    // 根据实际请求体结构定义对应属性
}
  1. 创建应用服务接口与实现:
public interface IMedistatWebHookAppService : IApplicationService
{
    Task<IActionResult> ReceiveEvents(WebhookEventRequestDto input);
}

public class MedistatWebHookAppService : ApplicationService, IMedistatWebHookAppService
{
    private readonly ILogger<MedistatWebHookAppService> _logger;

    public MedistatWebHookAppService(ILogger<MedistatWebHookAppService> logger)
    {
        _logger = logger;
        _logger.LogInformation($"Service Has Started {DateTime.Now:dd MMM yyyy}");
    }

    public async Task<IActionResult> ReceiveEvents(WebhookEventRequestDto input)
    {
        try
        {
            _logger.LogInformation($"Start logging email post request from events {DateTime.Now:dd MMM yyyy}");
            
            // 直接使用input处理业务逻辑,替代原代码中解析Request.Body的步骤
            // 若仍需原始请求体,可结合方式二实现

            return new OkResult();
        }
        catch (Exception ex)
        {
            return new BadRequestObjectResult(ex.Message);
        }
    }
}

方式二:直接读取原始请求体

如果需要像原Controller那样直接读取未序列化的原始请求体,可通过IHttpContextAccessor获取当前请求上下文:

  1. 注入IHttpContextAccessor到应用服务:
public class MedistatWebHookAppService : ApplicationService, IMedistatWebHookAppService
{
    private readonly ILogger<MedistatWebHookAppService> _logger;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public MedistatWebHookAppService(ILogger<MedistatWebHookAppService> logger, IHttpContextAccessor httpContextAccessor)
    {
        _logger = logger;
        _httpContextAccessor = httpContextAccessor;
        _logger.LogInformation($"Service Has Started {DateTime.Now:dd MMM yyyy}");
    }

    public async Task<IActionResult> ReceiveEvents()
    {
        try
        {
            _logger.LogInformation($"Start logging email post request from events {DateTime.Now:dd MMM yyyy}");
            
            var request = _httpContextAccessor.HttpContext.Request;
            // 重置请求流位置,避免因已被读取导致解析失败
            request.Body.Position = 0;
            
            var parser = new WebhookParser();
            var events = await parser.ParseEventsWebhookAsync(request.Body).ConfigureAwait(false);

            foreach(var emailEvent in events)
            {
                var dump = ObjectDumper.Dump(emailEvent);
                System.IO.File.WriteAllText(@"C:\Medistat\Logs\EmailEvents.txt", dump);
            }

            return new OkResult();
        }
        catch (Exception ex)
        {
            return new BadRequestObjectResult(ex.Message);
        }
    }
}

路由配置说明

ABP会自动为应用服务生成API控制器,默认路由为api/app/medistat-web-hook/receive-events。如果需要自定义路由(比如原Controller的/Events),可以:

  • 在应用服务接口或方法上添加[RemoteService(Name = "Events")]和[HttpPost]特性;
  • 或者手动创建Controller调用应用服务,保留原路由配置,将业务逻辑移至应用服务中。

内容的提问来源于stack exchange,提问作者Kirk De Villiers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:13:24