private async Task <ProgrammableServiceResponse> OnResponse(ProgrammableServiceContext context, ProgrammableServiceControllerInfo controllerInfo) { while (true) { var exists = await context.Store.Exists(context.NextRouteKey); if (!exists) { throw new Exception("Session does not exist."); } var routeInfoJson = await context.Store.Get(context.NextRouteKey); var routeInfo = ProgrammableServiceRoute.FromJson(routeInfoJson); if (controllerInfo.TheType.Name.Equals(routeInfo.FullControllerName)) { if (!controllerInfo.Methods.ContainsKey(routeInfo.ActionName)) { return(new ProgrammableServiceResponse { Message = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist", Type = ProgrammableServiceActionType.Release.ToString("G"), Label = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist", DataType = ProgrammableServiceDataTypes.Display, FieldType = ProgrammableServiceFieldTypes.Text }); } } else if (!_controllerActivator.ControllerCollection.ContainsKey(routeInfo.FullControllerName)) { return(new ProgrammableServiceResponse { Message = $"Could not find controller \"{routeInfo.FullControllerName}\"", Type = ProgrammableServiceActionType.Release.ToString("G"), Label = $"Could not find controller \"{routeInfo.FullControllerName}\"", DataType = ProgrammableServiceDataTypes.Display, FieldType = ProgrammableServiceFieldTypes.Text }); } else { controllerInfo = _controllerActivator.ControllerCollection[routeInfo.FullControllerName]; if (!controllerInfo.Methods.ContainsKey(routeInfo.ActionName)) { return(new ProgrammableServiceResponse { Message = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist", Type = ProgrammableServiceActionType.Release.ToString("G"), Label = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist", DataType = ProgrammableServiceDataTypes.Display, FieldType = ProgrammableServiceFieldTypes.Text }); } } var controller = (ProgrammableServiceControllerBase)_serviceProvider.GetRequiredService(controllerInfo.TheType); controller.Request = context.Request; controller.DataBag = context.DataBag; controller.Data = new Dictionary <string, string>(); controller.FormData = await controller.GetFormData(); var methodInfo = controllerInfo.Methods[routeInfo.ActionName].Method; object[] args = { }; var sessionResumeKey = $"_sessionResume.{context.Request.Mobile}"; ProgrammableServiceResponse response; if (context.Request.GetActionType() == ProgrammableServiceActionType.Initiation) { if (_configuration.EnableResumeSession) { //check if previous session exists var sessionResumeValStr = await context.Store.Get(sessionResumeKey); var sessionResumeList = JsonConvert.DeserializeObject <List <ResumeSessionInfo> >(sessionResumeValStr); if (await context.Store.Exists(sessionResumeKey) && string.Equals(controllerInfo.TheType.Name, sessionResumeList.LastOrDefault()?.ControllerName)) { //if the previous last entry is an initiation session...then just continue.... if (sessionResumeList.LastOrDefault().UserRequest.GetActionType() == ProgrammableServiceActionType.Initiation) { response = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args); } else { var previousSessionId = sessionResumeList.FirstOrDefault().UserRequest.SessionId; var keys = await context.Store.GetKeys(); var keysWithPreviousSessionId = keys.Where(k => k.StartsWith(previousSessionId)).ToList(); //copy everything from the previous session to the new session foreach (var key in keysWithPreviousSessionId) { var previousValue = await context.Store.Get(key); await context.Store.Set(key.Replace(previousSessionId, context.Request.SessionId), previousValue); } controller.FormData = await controller.GetFormData(); //important step, if not, FormData is always NULL var sessionResumeMethod = controllerInfo.Methods.Values.FirstOrDefault(m => m.IsSessionResumeMethod); if (sessionResumeMethod == null) { throw new Exception($"no method found that has HandleResumeSession attribute"); } await context.Store.Delete(sessionResumeKey); //so we don't have chaff data for this user response = await(Task <ProgrammableServiceResponse>) sessionResumeMethod.Method.Invoke(controller, new [] { sessionResumeList }); } } else { //just call the initiation handler... response = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args); } } else { response = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args); } } else { response = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args); } if (!response.IsRelease) { if (!response.IsRedirect) { if (_configuration.EnableResumeSession) { List <ResumeSessionInfo> sessionResumeList; if (await context.Store.Exists(sessionResumeKey)) { var sessionResumeValStr = await context.Store.Get(sessionResumeKey); sessionResumeList = JsonConvert.DeserializeObject <List <ResumeSessionInfo> >(sessionResumeValStr); sessionResumeList.Add(new ResumeSessionInfo { UserRequest = context.Request, ServiceResponse = response, MethodName = methodInfo.Name, ControllerName = controllerInfo.TheType.Name }); } else { sessionResumeList = new List <ResumeSessionInfo> { new ResumeSessionInfo { UserRequest = context.Request, ServiceResponse = response, MethodName = methodInfo.Name, ControllerName = controllerInfo.TheType.Name } }; } await context.Store.Set(sessionResumeKey, JsonConvert.SerializeObject(sessionResumeList)); } } await context.Store.Set(context.NextRouteKey, response.NextRoute); } else { if (_configuration.EnableResumeSession) { await context.Store.Delete(sessionResumeKey); } } if (response.IsRedirect) { continue; } return(response); } }
private async Task <ProgrammableServiceResponse> OnResponse(ProgrammableServiceContext context, ProgrammableServiceControllerInfo controllerInfo) { while (true) { var exists = await context.Store.Exists(context.NextRouteKey); if (!exists) { throw new Exception("Session does not exist."); } var routeInfoJson = await context.Store.Get(context.NextRouteKey); var routeInfo = ProgrammableServiceRoute.FromJson(routeInfoJson); if (controllerInfo.TheType.Name.Equals(routeInfo.FullControllerName)) { if (!controllerInfo.Methods.ContainsKey(routeInfo.ActionName)) { return(new ProgrammableServiceResponse { Message = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist", Type = ProgrammableServiceActionType.Release.ToString("G"), Label = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist", DataType = ProgrammableServiceDataTypes.Display, FieldType = ProgrammableServiceFieldTypes.Text }); } } else if (!_controllerActivator.ControllerCollection.ContainsKey(routeInfo.FullControllerName)) { return(new ProgrammableServiceResponse { Message = $"Could not find controller \"{routeInfo.FullControllerName}\"", Type = ProgrammableServiceActionType.Release.ToString("G"), Label = $"Could not find controller \"{routeInfo.FullControllerName}\"", DataType = ProgrammableServiceDataTypes.Display, FieldType = ProgrammableServiceFieldTypes.Text }); } else { controllerInfo = _controllerActivator.ControllerCollection[routeInfo.FullControllerName]; if (!controllerInfo.Methods.ContainsKey(routeInfo.ActionName)) { return(new ProgrammableServiceResponse { Message = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist", Type = ProgrammableServiceActionType.Release.ToString("G"), Label = $"Action handler \"{routeInfo.ActionName}\" on controller \"{controllerInfo.TheType.Name}\" does not exist", DataType = ProgrammableServiceDataTypes.Display, FieldType = ProgrammableServiceFieldTypes.Text }); } } var controller = (ProgrammableServiceControllerBase)_serviceProvider.GetRequiredService(controllerInfo.TheType); controller.Request = context.Request; controller.DataBag = context.DataBag; controller.Data = new Dictionary <string, string>(); controller.FormData = await controller.GetFormData(); var methodInfo = controllerInfo.Methods[routeInfo.ActionName].Method; object[] args = { }; var response = await(Task <ProgrammableServiceResponse>) methodInfo.Invoke(controller, args); if (!response.IsRelease) { await context.Store.Set(context.NextRouteKey, response.NextRoute); } if (response.IsRedirect) { continue; } return(response); } }