public async Task ProcessStaticCommandRequest(IDotvvmRequestContext context) { JObject postData; using (var jsonReader = new JsonTextReader(new StreamReader(context.HttpContext.Request.Body))) { postData = JObject.Load(jsonReader); } // validate csrf token context.CsrfToken = postData["$csrfToken"].Value <string>(); CsrfProtector.VerifyToken(context, context.CsrfToken); var command = postData["command"].Value <string>(); var arguments = postData["args"] as JArray; var lastDot = command.LastIndexOf('.'); var typeName = command.Remove(lastDot); var methodName = command.Substring(lastDot + 1); var methodInfo = Type.GetType(typeName).GetMethod(methodName); if (!methodInfo.IsDefined(typeof(AllowStaticCommandAttribute))) { throw new DotvvmHttpException($"This method cannot be called from the static command. If you need to call this method, add the '{nameof(AllowStaticCommandAttribute)}' to the method."); } var target = methodInfo.IsStatic ? null : arguments[0].ToObject(methodInfo.DeclaringType); var methodArguments = arguments.Skip(methodInfo.IsStatic ? 0 : 1) .Zip(methodInfo.GetParameters(), (arg, parameter) => arg.ToObject(parameter.ParameterType)) .ToArray(); var actionInfo = new ActionInfo { IsControlCommand = false, Action = () => methodInfo.Invoke(target, methodArguments) }; var filters = context.Configuration.Runtime.GlobalFilters.OfType <ICommandActionFilter>() .Concat(ActionFilterHelper.GetActionFilters <ICommandActionFilter>(methodInfo)) .ToArray(); var result = await ExecuteCommand(actionInfo, context, filters); using (var writer = new StreamWriter(context.HttpContext.Response.Body)) { var json = ViewModelSerializer.BuildStaticCommandResponse(context, result); writer.WriteLine(json); } }
public async Task ProcessStaticCommandRequest(IDotvvmRequestContext context) { try { JObject postData; using (var jsonReader = new JsonTextReader(new StreamReader(context.HttpContext.Request.Body))) { postData = JObject.Load(jsonReader); } // validate csrf token context.CsrfToken = postData["$csrfToken"].Value <string>(); CsrfProtector.VerifyToken(context, context.CsrfToken); var command = postData["command"].Value <string>(); var arguments = postData["args"] as JArray; var executionPlan = StaticCommandBindingCompiler.DecryptJson(Convert.FromBase64String(command), context.Services.GetService <IViewModelProtector>()) .Apply(StaticCommandBindingCompiler.DeserializePlan); var actionInfo = new ActionInfo { IsControlCommand = false, Action = () => { return(ExecuteStaticCommandPlan(executionPlan, new Queue <JToken>(arguments), context)); } }; var filters = context.Configuration.Runtime.GlobalFilters.OfType <ICommandActionFilter>() .Concat(executionPlan.GetAllMethods().SelectMany(m => ActionFilterHelper.GetActionFilters <ICommandActionFilter>(m))) .ToArray(); var result = await ExecuteCommand(actionInfo, context, filters); await OutputRenderer.WriteStaticCommandResponse(context, ViewModelSerializer.BuildStaticCommandResponse(context, result)); } finally { StaticCommandServiceLoader.DisposeStaticCommandServices(context); } }