/// <summary> /// Submits a form. /// </summary> /// <param name="formId"> /// The ID of the form to submit. /// </param> /// <param name="data"> /// The form data to submit. /// </param> /// <param name="files"> /// The file data to submit. /// </param> /// <param name="payload"> /// Extra data related to the submission. /// </param> /// <param name="options"> /// The options for this submission. /// </param> /// <param name="context"> /// The contextual information for the form request. /// </param> /// <returns> /// The result of the submission. /// </returns> public SubmissionResult SubmitForm(Guid formId, IEnumerable <FieldSubmission> data, IEnumerable <FileFieldSubmission> files, IEnumerable <PayloadSubmission> payload, SubmissionOptions options, FormRequestContext context) { // Is the form ID valid? var form = Forms.Retrieve(formId); if (form == null) { return(new SubmissionResult() { Success = false }); } // Create submission context. var submissionContext = new FormSubmissionContext() { Files = files, Data = data, Form = form, Payload = payload, CurrentPage = context.CurrentPage, HttpContext = context.HttpContext, Services = context.Services, UmbracoContext = context.UmbracoContext, UmbracoHelper = context.UmbracoHelper, SubmissionId = Guid.NewGuid(), ExtraContext = new Dictionary <string, object>(), SubmissionCancelled = false }; // Invoke submitting event (gives listeners a chance to change the submission). Submitting?.Invoke(submissionContext); // Fail the form submission if SubmissionCancelled is true. if (submissionContext.SubmissionCancelled) { return(new SubmissionResult() { Success = false }); } // Validate against native field validations. foreach (var field in form.Fields) { var fieldId = field.Id; var value = data.Where(x => x.FieldId == fieldId) .SelectMany(x => x.FieldValues); if (!field.IsValid(value)) { return(new SubmissionResult() { Success = false }); } } // Validate? if (options.Validate) { var valuesById = data.GroupBy(x => x.FieldId).Select(x => new { Id = x.Key, Values = x.SelectMany(y => y.FieldValues).ToList() }).ToDictionary(x => x.Id, x => x.Values); var filesById = files.GroupBy(x => x.FieldId).Select(x => new { Id = x.Key, Values = x.Select(y => y).ToList() }).ToDictionary(x => x.Id, x => x.Values); foreach (var field in form.Fields) { var validations = field.Validations .Select(x => Validations.Retrieve(x)) .ToList(); if (!validations.Any()) { continue; } var validationContext = new ValidationContext() { Field = field, Form = form }; foreach (var validation in validations) { var dataValues = valuesById.ContainsKey(field.Id) ? valuesById[field.Id] : new List <string>(); var fileValues = filesById.ContainsKey(field.Id) ? filesById[field.Id] : new List <FileFieldSubmission>(); var isValid = validation .IsValueValid(dataValues, fileValues, validationContext); if (!isValid) { return(new SubmissionResult() { Success = false }); } } } } // Prepare the form handlers. // This occurs on the current thread in case the handler needs information // only available in the current thread. var enabledHandlers = form.Handlers .Where(x => x.Enabled) .ToArray(); try { foreach (var handler in enabledHandlers) { handler.PrepareHandleForm(submissionContext); } } catch (Exception ex) { Logger.Error <Submissions_Instance>(ex, PreHandlerError); return(new SubmissionResult() { Success = false }); } // Initiate form handlers on a new thread (they may take some time to complete). var task = new Task(() => { foreach (var handler in enabledHandlers) { handler.HandleForm(submissionContext); } }); task.ContinueWith(FormHandlersExceptionHandler, TaskContinuationOptions.OnlyOnFaulted); task.Start(); // Return success. return(new SubmissionResult() { Success = true }); }
/// <summary> /// Submits a form. /// </summary> /// <param name="formId"> /// The ID of the form to submit. /// </param> /// <param name="data"> /// The form data to submit. /// </param> /// <param name="files"> /// The file data to submit. /// </param> /// <param name="payload"> /// Extra data related to the submission. /// </param> /// <param name="options"> /// The options for this submission. /// </param> /// <param name="context"> /// The contextual information for the form request. /// </param> /// <returns> /// The result of the submission. /// </returns> public static SubmissionResult SubmitForm(Guid formId, IEnumerable <FieldSubmission> data, IEnumerable <FileFieldSubmission> files, IEnumerable <PayloadSubmission> payload, SubmissionOptions options, FormRequestContext context) { // Is the form ID valid? var form = Forms.Retrieve(formId); if (form == null) { return(new SubmissionResult() { Success = false }); } // Create submission context. var submissionContext = new FormSubmissionContext() { Files = files, Data = data, Form = form, Payload = payload, CurrentPage = context.CurrentPage, HttpContext = context.HttpContext, Services = context.Services, UmbracoContext = context.UmbracoContext, UmbracoHelper = context.UmbracoHelper, SubmissionId = Guid.NewGuid(), ExtraContext = new Dictionary <string, object>() }; // Invoke submitting event (gives listeners a chance to change the submission). Submitting?.Invoke(submissionContext); // Validate? if (options.Validate) { var valuesById = data.GroupBy(x => x.FieldId).Select(x => new { Id = x.Key, Values = x.SelectMany(y => y.FieldValues).ToList() }).ToDictionary(x => x.Id, x => x.Values); foreach (var field in form.Fields) { var validations = field.Validations.Select(x => Validations.Retrieve(x)).ToList(); foreach (var validation in validations) { //TODO: var validationResult = validation.Validate(form, field, valuesById); } } } // Prepare the form handlers. // This occurs on the current thread in case the handler needs information // only available in the current thread. try { foreach (var handler in form.Handlers) { handler.PrepareHandleForm(submissionContext); } } catch (Exception ex) { LogHelper.Error <Submissions_Instance>(PreHandlerError, ex); return(new SubmissionResult() { Success = false }); } // Initiate form handlers on a new thread (they may take some time to complete). var t = new Thread(() => { try { foreach (var handler in form.Handlers) { handler.HandleForm(submissionContext); } } catch (Exception ex) { LogHelper.Error <Submissions_Instance>(HandlerError, ex); } }); t.IsBackground = true; t.Start(); // Return success. return(new SubmissionResult() { Success = true }); }