2017-09-26 2 views
1

Hallo alle, ich versuche, einige Daten von einem Login-Controller in den Benutzerdatenspeicher zu speichern.Zugriff auf Benutzerdaten über den StateClient für einen Localhost-Bot, der nicht ohne Aktivität registriert ist

[HttpGet, Route("api/{channelId}/{userId}/authorize")] 
public async System.Threading.Tasks.Task<HttpResponseMessage> Authorize(string channelId, string userId, string code) 
{ 
    string protocalAndDomain = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority); 

    AuthenticationContext ac = new AuthenticationContext(Constants.AD_AUTH_CONTEXT); 
    ClientCredential cc = new ClientCredential(Constants.AD_CLIENT_ID, Constants.AD_CLIENT_SECRET); 
    AuthenticationResult ar = await ac.AcquireTokenByAuthorizationCodeAsync(code, new Uri(protocalAndDomain + "/api/" + channelId + "/" + userId + "/authorize"), cc); 
    MicrosoftAppCredentials.TrustServiceUrl(protocalAndDomain, DateTime.Now.AddHours(1)); 

    if (!String.IsNullOrEmpty(ar.AccessToken)) 
    { 
     // Store access token & User Id to bot state 
     //var botCred = new MicrosoftAppCredentials(Constants.MS_APP_ID, Constants.MS_APP_PASSWORD); 
     //https://state.botframework.com 

     using (var sc = new StateClient(new Uri("http://localhost:3979/"))) 
      if (sc != null) 
      { 
       var botData = new BotData(data: null, eTag: "*"); 
       botData.SetProperty("accessToken", ar.AccessToken); 
       botData.SetProperty("userEmail", ar.UserInfo.DisplayableId); 

       //i get a 401 response here 
       await sc.BotState.SetUserDataAsync(channelId, userId, botData); 
      } 


     var response = Request.CreateResponse(HttpStatusCode.Moved); 
     response.Headers.Location = new Uri("/loggedin.html", UriKind.Relative); 
     return response; 

    } 
    else 
     return Request.CreateResponse(HttpStatusCode.Unauthorized); 
} 

Ich habe gesehen, Beispiele in dem Sie das AppId ein appPassword verwenden können, um den Bot Zustand zugreifen, aber nach meinem Verständnis die sind nicht verfügbar, bis Sie Ihr Bot in dem Azuer Anwendungsportal veröffentlicht/regested die i kann derzeit nicht tun.

oder dass Sie über die Aktivität darauf zugreifen können, auf die ich wiederum keinen Zugriff habe.

Dies ist eigentlich nur eine temporäre Lösung Mein Plan ist es, die Benutzerdaten in Azure-Tabellenspeicher zu speichern, aber ich möchte in der Zwischenzeit eine temporäre Lösung; Ich überlege gerade, ein Wörterbuch in eine lokale Textdatei zu serialisieren und zu deserialisieren, aber das erscheint mir jetzt wie ein Overkill und es scheint albern, dass ich die Daten für den Benutzer nicht lokal speichern kann, ohne dass meine App in Blau hinterlegt ist.

Prost jede Hilfe wird sehr geschätzt.

Antwort

0

Mit dieser Zeile:

var sc = new StateClient(new Uri("http://localhost:3979/")) 

Sie anweist, die BotBuilder einen Statusdienst bei http://localhost:3979/ zu verwenden, aber es gibt keinen State Service an diesem Endpunkt.

protected void Application_Start() 
{ 
    Conversation.UpdateContainer(
     builder => 
      { 
       builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly())); 

       var store = new InMemoryDataStore(); // volatile in-memory store 

       builder.Register(c => store) 
        .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore) 
        .AsSelf() 
        .SingleInstance(); 


      }); 

    GlobalConfiguration.Configure(WebApiConfig.Register); 
} 

Hinweis:

Wenn Sie eine temporäre Lösung haben wollen, bis Sie Azure Tabellen Speicher hinzufügen, können Sie die InMemoryDataStore verwenden, um dies erfordert die Azure-Erweiterungen nuget https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/

Sobald die InMemoryDataStore zu verpacken registriert ist, können Sie mit etwas wie:

var message = new Activity() 
       { 
        ChannelId = ChannelIds.Directline, 
        From = new ChannelAccount(userId, userName), 
        Recipient = new ChannelAccount(botId, botName), 
        Conversation = new ConversationAccount(id: conversationId), 
        ServiceUrl = serviceUrl 
       }.AsMessageActivity(); 

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message)) 
{ 
    var botDataStore = scope.Resolve<IBotDataStore<BotData>>(); 
    var key = new AddressKey() 
    { 
     BotId = message.Recipient.Id, 
     ChannelId = message.ChannelId, 
     UserId = message.From.Id, 
     ConversationId = message.Conversation.Id, 
     ServiceUrl = message.ServiceUrl 
    }; 
    var userData = await botDataStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None); 

    userData.SetProperty("key 1", "value1"); 
    userData.SetProperty("key 2", "value2"); 

    await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None); 
    await botDataStore.FlushAsync(key, CancellationToken.None); 
} 
zugreifen
Verwandte Themen