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

ASP.NET Web API对接Bot Framework:serviceUrl配置与响应回传问题

问题:ASP.NET Web API对接Bot Builder的请求响应流程问题

我已基于ASP.NET C#搭建Bot Builder及配套Web API,相关代码如下:

一、现有代码实现

1. BotController代码

// This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot
// implementation at runtime. Multiple different IBot implementations running at different endpoints can be
// achieved by specifying a more specific type for the bot constructor argument.
[ApiController]
public class BotController : ControllerBase
{
    private readonly IBotFrameworkHttpAdapter _adapter;
    private readonly IBot _bot;

    public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
    {
        _adapter = adapter;
        _bot = bot;
    }

    [HttpPost, HttpGet]
    [Route("api/messages")]
    public async Task PostAsync()
    {
        await _adapter.ProcessAsync(Request, Response, _bot);
    }


    // Health check endpoint
    [HttpGet]
    [Route("health")]
    public IActionResult HealthCheck()
    {
        // Implement your availability check logic here
        bool isApiAvailable = CheckAPIAvailability();

        if (isApiAvailable)
        {
            return Ok("API is available");
        }
        else
        {
            return StatusCode(503, "API is unavailable");
        }
    }

    private bool CheckAPIAvailability()
    {
        // Implement your logic to check API availability here
        // This could involve checking database connections, external dependencies, etc.
        // For simplicity, let's return true if the API is running
        return true;
    }

}

2. 向/api/messages发送conversationUpdate请求的代码

var payload = new
{
    type = "conversationUpdate",
    membersAdded = new[]
    {
        new { id = "bot1", name = "Bot 1" },
        new { id = "user1", name = "User 1" },
    },
    membersRemoved = new object[0],
    channelId = "test",
    conversation = new { id = "conversation1" },
    recipient = new { id = "bot1", name = "Bot 1" , role="bot"},
    from = new { id = "user1", name = "User 1", role="user" },
    locale = "en-US",
    id = "conversation1",
    //serviceUrl=

};
string jsonPayload = JsonConvert.SerializeObject(payload, Formatting.Indented);
HttpContent content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
var httpClient = new HttpClient();
var response = await httpClient.PostAsync($"http://localhost:5000/api/messages", content);

二、serviceUrl配置引发的报错

尝试将serviceUrl设置为http://localhost:5000/api/messages时,API返回500内部服务器错误:

{StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
  Date: Mon, 13 May 2024 11:04:51 GMT
  Server: Kestrel
  Content-Length: 0
}}

控制台日志显示异常:

fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HN3J7I0HVPRG", Request id "0HN3J7I0HVPRG:00000002": An unhandled exception was thrown by the application.
      Microsoft.Bot.Schema.ErrorResponseException: Operation returned an invalid status code 'NotFound'
         at Microsoft.Bot.Connector.Conversations.ReplyToActivityWithHttpMessagesAsync(String conversationId, String activityId, Activity activity, Dictionary`2 customHeaders, CancellationToken cancellationToken)
         at Microsoft.Bot.Connector.ConversationsExtensions.ReplyToActivityAsync(IConversations operations, String conversationId, String activityId, Activity activity, CancellationToken cancellationToken)
         at Microsoft.Bot.Builder.CloudAdapterBase.SendActivitiesAsync(ITurnContext turnContext, Activity[] activities, CancellationToken cancellationToken)
         at Microsoft.Bot.Builder.TurnContext.<>c__DisplayClass31_0.<<SendActivitiesAsync>g__SendActivitiesThroughAdapter|1>d.MoveNext()
      --- End of stack trace from previous location ---
         at Microsoft.Bot.Builder.TurnContext.SendActivityAsync(IActivity activity, CancellationToken cancellationToken)
         at PteroBotWebAPI.AdapterWithErrorHandler.<>c__DisplayClass0_0.<<-ctor>b__0>d.MoveNext() in D:\Projects\ProMate\Source\PetroBot\PteroBotWebAPI\AdapterWithErrorHandler.cs:line 30
      --- End of stack trace from previous location ---
         at Microsoft.Bot.Builder.BotAdapter.RunPipelineAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken)
         at Microsoft.Bot.Builder.CloudAdapterBase.ProcessActivityAsync(AuthenticateRequestResult authenticateRequestResult, Activity activity, BotCallbackHandler callback, CancellationToken cancellationToken)
         at Microsoft.Bot.Builder.CloudAdapterBase.ProcessActivityAsync(String authHeader, Activity activity, BotCallbackHandler callback, CancellationToken cancellationToken)
         at Microsoft.Bot.Builder.Integration.AspNet.Core.CloudAdapter.ProcessAsync(HttpRequest httpRequest, HttpResponse httpResponse, IBot bot, CancellationToken cancellationToken)
         at PteroBotWebAPI.Controllers.BotController.PostAsync() in D:\Projects\ProMate\Source\PetroBot\PteroBotWebAPI\Controllers\BotController.cs:line 43
         at lambda_method6(Closure , Object )
         at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
         at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

三、后续尝试及核心疑问

后续将serviceUrl设置为http://localhost:5000/api/response,并新增以下路由代码:

// Endpoint to handle any routes starting with api/response
[HttpPost]
[Route("api/response/{*path}")]
public async Task HandleBotResponseAsync()
{
    // what should be here?!
}

此时Bot已将响应发送到该端点,但不清楚如何将Bot的响应回传给发起初始请求的用户。

请问如何解决上述报错,实现通过ASP.NET Web API向Bot发送请求并获取响应的完整流程?


内容的提问来源于stack exchange,提问作者Inevitable

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 08:17:32