我真的疯了,试图解决这个问题,但我所做的一切似乎都有所作为。当我导航到localhost:3978/api/callback
时,它会抛出
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:3978/api/callback'.
</Message>
<MessageDetail>
No action was found on the controller 'Callback' that matches the request.
</MessageDetail>
</Error>
这是我的Controllers / CallbackController.cs中的控制器
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using Autofac;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
namespace VSTF_RD_Bot.Controllers
{
public class CallbackController : ApiController
{
[HttpGet]
[Route("api/Callback")]
public async Task<HttpResponseMessage> Callback([FromUri] string state, [FromUri] string code)
{
//parse out the userId and convoId from states parameter
string[] states = state.Split(new[] { "," }, StringSplitOptions.None);
string userId = states[0];
string conversationId = states[1];
// Check if the bot is running against emulator
var connectorType = HttpContext.Current.Request.IsLocal ? ConnectorType.Emulator : ConnectorType.Cloud;
// Exchange the Facebook Auth code with Access toekn
var token = await AdHelpers.ExchangeCodeForAccessToken(userId, conversationId, code, "redirect_uri");
// Create the message that is send to conversation to resume the login flow
var msg = new Message
{
Text = $"token:{token}",
From = new ChannelAccount { Id = userId },
To = new ChannelAccount { Id = Constants.botId },
ConversationId = conversationId
};
var reply = await Conversation.ResumeAsync(Constants.botId, userId, conversationId, msg, connectorType: connectorType);
// Remove the pending message because login flow is complete
IBotData dataBag = new JObjectBotData(reply);
PendingMessage pending;
if (dataBag.PerUserInConversationData.TryGetValue("pendingMessage", out pending))
{
dataBag.PerUserInConversationData.RemoveValue("pendingMessage");
var pendingMessage = pending.GetMessage();
reply.To = pendingMessage.From;
reply.From = pendingMessage.To;
// Send the login success asynchronously to user
var client = Conversation.ResumeContainer.Resolve<IConnectorClient>(TypedParameter.From(connectorType));
await client.Messages.SendMessageAsync(reply);
return Request.CreateResponse("You are now logged in! Continue talking to the bot.");
}
else
{
// Callback is called with no pending message as a result the login flow cannot be resumed.
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, new InvalidOperationException("Cannot resume!"));
}
}
}
}
我在这里缺少什么?
这是我的webApiconfig.cs
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace VSTF_RD_Bot
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Json settings
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
};
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
答案 0 :(得分:1)
制作你的控制器
[HttpGet]
[Route("api/Callback/{state}/{code}")]
public async Task<HttpResponseMessage> Callback(string state, string code)
{
并请求网址
"localhost:3978/api/Callback/samplestate/samplecode"