Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以对多个Microsoft机器人程序使用相同的端点_C#_Botframework_Skypedeveloper - Fatal编程技术网

C# 是否可以对多个Microsoft机器人程序使用相同的端点

C# 是否可以对多个Microsoft机器人程序使用相同的端点,c#,botframework,skypedeveloper,C#,Botframework,Skypedeveloper,我正在尝试新的微软机器人框架来构建Skype机器人。 我想知道是否有可能为几个机器人注册相同的端点 我看到了Microsoft示例,它们使用web.config来存储: <add key="MicrosoftAppId" value="GUID" /> <add key="MicrosoftAppPassword" value="PASSWORD" /> 并使用[BotAuthentication]属性解决所有问题 如果相同的端点可以重复用于多个机器人,我应该如何处

我正在尝试新的微软机器人框架来构建Skype机器人。 我想知道是否有可能为几个机器人注册相同的端点

我看到了Microsoft示例,它们使用web.config来存储:

<add key="MicrosoftAppId" value="GUID" />
<add key="MicrosoftAppPassword" value="PASSWORD" />

并使用
[BotAuthentication]
属性解决所有问题

如果相同的端点可以重复用于多个机器人,我应该如何处理身份验证

谢谢

我可以为同一web服务(bot)和同一端点注册多个bot框架吗

如果这就是您的意思,那么答案是否定的,至少对于Bot Builder SDK是否定的。对于一个端点,只能使用一组凭据。我认为使用相同的Microsoft应用程序ID(和密码)进行多个机器人注册没有问题,但目前不支持

您的用例是什么?你想为同一个机器人拥有多个频道身份(例如在Facebook上)?如果您真的需要,我相信您可以通过自己实现身份验证来实现这一点(而不是依赖SDK)

更新

一个简单的解决方法是有多个端点,每个bot一个端点,将工作委托给一个公共类。例如,您为bot1注册
/bot1/api/messages/
,为bot2注册
/bot2/api/messages
,每个控制器使用
BotAuthentication
属性和给定bot的appId和secret。您可以使用如下属性:

[BotAuthentication(MicrosoftAppId="bot1AppId", MicrosoftAppPassword="bot1AppPwd")]
public class Bot1MessagesController : ApiController
...

多租户实现-可能的解决方案

更改消息终结点的路由以采用通配符,如下所示:

    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    [Route("messages/{*wildcard}")]
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
实施

public class MultiTentantBotAuthenticationAttribute : BotAuthentication
{
    public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        this.MicrosoftAppId = actionContext.Request.RequestUri.Segments.Last();

        await base.OnAuthorizationAsync(actionContext, cancellationToken);
    }
}
如果您需要bot中的代码来知道它在哪个应用程序中运行,您可以通过userdata将其传递,如下所示:

    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    [Route("messages/{*wildcard}")]
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        var botId = Request.RequestUri.Segments.Last(); // Validate against your database / configuration

        try
        {
            if (activity.Type == ActivityTypes.Message)
            {
                // https://docs.botframework.com/en-us/csharp/builder/sdkreference/stateapi.html

                var stateClient = activity.GetStateClient();
                BotData userData = await stateClient.BotState.GetUserDataAsync(activity.ChannelId, activity.From.Id);
                userData.SetProperty("ApplicationAccountBotId", botId);
                await stateClient.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData);

                await Conversation.SendAsync(activity, () => actionDialog);
            }
            else
            {
                HandleSystemMessage(activity);
            }
        }
        catch (Exception exception)
        {
            await logger.ErrorAsync(exception);
        }

        return Request.CreateResponse(HttpStatusCode.OK);
    }
//
///帖子:api/Messages
///接收来自用户的消息并回复
/// 
[路由(“消息/{*通配符}”)]
公共异步任务发布([FromBody]活动)
{
var botId=Request.RequestUri.Segments.Last();//根据数据库/配置进行验证
尝试
{
if(activity.Type==ActivityTypes.Message)
{
// https://docs.botframework.com/en-us/csharp/builder/sdkreference/stateapi.html
var stateClient=activity.GetStateClient();
BotData userData=await stateClient.BotState.GetUserDataAsync(activity.ChannelId,activity.From.Id);
SetProperty(“ApplicationAccountBotId”,botId);
等待stateClient.BotState.SetUserDataAsync(activity.ChannelId、activity.From.Id、userData);
等待对话。SendAsync(活动,()=>actionDialog);
}
其他的
{
HandleSystemMessage(活动);
}
}
捕获(异常)
{
等待logger.ErrorAsync(异常);
}
返回Request.CreateResponse(HttpStatusCode.OK);
}

然后,您可以在对话框/bot代码中访问用户数据。

我需要两个bot,但我想用同一个端点管理它们。因此,您希望同一端点具有多个bot标识。我相信您唯一的选择是自己实现身份验证(查看Microsoft应用程序ID列表),正如我在回答中提到的。实际上有一个解决方法,请参阅我更新的回答。但是如果我想随着时间的推移添加机器人,我必须每次重新编译以创建新的机器人。我想只有一个控制器,以避免编写新代码和重新编译的网站!然后,您必须编写自己的身份验证机制,该机制使用可从配置文件读取的白名单AppID列表。信息方面,在BotFramework 3.13.1中,要覆盖的方法现在称为OnActionExecutionGasSync。另外,为了在使用Conversation类时保留身份验证,您需要更新其容器以从HttpContext用户标识检索MicrosoftAppCredentials,我在注册Autofac模块的地方添加了此代码
Conversation.UpdateContainer(cbuilder=>{cbuilder.register(c=>((ClaimsIdentity)HttpContext.Current.User.Identity).GetCredentialsFromClaims()).AsSelf().InstancePerLifetimeScope();});
    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    [Route("messages/{*wildcard}")]
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        var botId = Request.RequestUri.Segments.Last(); // Validate against your database / configuration

        try
        {
            if (activity.Type == ActivityTypes.Message)
            {
                // https://docs.botframework.com/en-us/csharp/builder/sdkreference/stateapi.html

                var stateClient = activity.GetStateClient();
                BotData userData = await stateClient.BotState.GetUserDataAsync(activity.ChannelId, activity.From.Id);
                userData.SetProperty("ApplicationAccountBotId", botId);
                await stateClient.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData);

                await Conversation.SendAsync(activity, () => actionDialog);
            }
            else
            {
                HandleSystemMessage(activity);
            }
        }
        catch (Exception exception)
        {
            await logger.ErrorAsync(exception);
        }

        return Request.CreateResponse(HttpStatusCode.OK);
    }