Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • David 28 posts 199 karma points
    Jul 08, 2020 @ 16:37
    David
    0

    Form Submission Error

    I am in the process of creating a data driven multi step form, which returns the same view(template) each time the "Next/Previous" buttons are clicked.

    However, when clicking "Next" (submit) I get the following:

    enter image description here

    Here is the main view (template) that will always be returned each time "next/previous" is clicked. (see below)

      @inherits Umbraco.Web.Mvc.UmbracoViewPage<SchemeWizardStepsViewModel>
    @using QuoteBeater.ViewModels;
    
    @{
        Layout = "quoteBeater.cshtml";
    } 
    <section>
            <div class="container">
                <h1>@Model.Scheme.SchemeName</h1>
    
                <div class="wizard-steps">
                    @foreach (var wizardStep in Model.Steps.OrderBy(x => x.WizardStep))
                    {
                        if (wizardStep.WizardStep == Model.CurrentWizardStep)
                        {
                            <span class="wizard-step active">@wizardStep.GroupName</span>
                        }
                        else
                        {
                            <span class="wizard-step">@wizardStep.GroupName</span>
                        }
                    }
                </div>
    
                @for (int i = 0; i < Model.Steps.OrderBy(x => x.WizardStep).ToList().Count; i++)
                {
                    if (Model.Steps[i].WizardStep == Model.CurrentWizardStep)
                    {
                        WizardStepViewModel wizardStepViewModel = Model.Steps[i];
                        @Html.EditorFor(model => wizardStepViewModel, "WizardStepEditor", new { id = "wizStepID" + Model.Steps[i].WizardStep.ToString() })
                        break;
                    }
                }
    
            </div>
        </section>
    

    Here is the view with "beginUmbracoForm" and the questions (used with Html.EditorFor)

    @model WizardStepViewModel
    @using QuoteBeater.ViewModels;
    @using QuoteBeater.Website.Models;
    @using QuoteBeater.Controllers;
    @using System.ComponentModel;
    @using System.Linq;
    
    
    @using (Html.BeginUmbracoForm("HandleWizardStepAction", "QuoteForm"))
    {
        @Html.HiddenFor(x => x.GroupId, new { @id = "GroupID" })
        @Html.HiddenFor(x => x.GroupName)
        @Html.HiddenFor(x => x.IsValidStep)
        @Html.HiddenFor(x => x.WizardStep)
        @Html.HiddenFor(x => x.FinalWizardStep)
    
    
        @Html.AntiForgeryToken()
        @Html.ValidationSummary()
    
        <h3>@Model.GroupName</h3>
    
        for (int i = 0; i < Model.Questions.Count; i++)
        {
            //Questions Render Here
        }
    
        <div class="text-left">
            @if (Model.WizardStep > 1)
            {
                <input type="submit" id="previousSubmit" name="submitButton" class="btn btn-primary btn-lg" value="Previous" formnovalidate />
            }
            @if (Model.WizardStep == Model.FinalWizardStep)
            {
                <input type="submit" name="submitButton" class="btn btn-success btn-lg" value="Finish" />
            }
            else
            {
                <input type="submit" id="nextSubmit" name="submitButton" class="btn btn-primary btn-lg" value="Next" />
            }
        </div>
    

    Here is my model

    public class SchemeWizardStepsViewModel : PublishedContentWrapped
        {
    
            public SchemeWizardStepsViewModel(IPublishedContent content) : base(content) { }
    
            public Scheme Scheme { get; set; }
            public int NumberOfWizardSteps { get; set; }
            public int CurrentWizardStep { get; set; }
            public List<WizardStepViewModel> Steps { get; set; }
    
    
            public void PersistAnswers(int currentWizardStep, WizardStepViewModel currentWizardStepViewModel)
            {
                for (int i = 0; i < Steps.Count; i++)
                {
                    if (Steps[i].WizardStep == currentWizardStep)
                    {
                        List<QuestionViewModel> questions = Steps[i].Questions;
    
                        for (int j = 0; j < questions.Count; j++)
                        {
    
                            //check for nulls
                            if (questions[j] != null)
                            {
                                var answer = currentWizardStepViewModel.Questions.FirstOrDefault(f => f.Question.ID == questions[j].Question.ID).Answer;
    
                                if (answer != null)
                                {
    
                                    questions[j].Answer.AnswerValue = answer.AnswerValue;
                                }
    
                            }
                        }
                    }
                }
    
    
            }
        }
    

    Here is my Controller

    namespace QuoteBeater.Controllers
    {
        public class QuoteFormController : RenderMvcController
        {
    
            public static LogicInstance instance = _Code.SiteSingleton.LogicInstance_ServiceSingleton.Instance;
            public static TeledynamicsWebsiteContext context = instance.GetWebsiteContext(ConfigurationManager.ConnectionStrings["teledynamicsWebsiteDBContext"].ToString());
    
    
            public static ContentModel contentModel { get; set; }
    
            public QuoteFormController() { }
    
            public override ActionResult Index(ContentModel model)
            {
    
                contentModel = model;
                string schemeType = "Private";
    
                ModelState.Clear();
    
                Scheme scheme = context.Schemes_GetAll().FirstOrDefault(x => x.SchemeName.ToLower().Contains(schemeType.ToLower()));
                List<SchemeGroup> schemeGroups = context.Schemes_GetSchemeGroups(scheme.ID);
                List<Question> schemeQuestions = context.Schemes_GetSchemeQuestions(scheme.ID);
    
                foreach (var item in schemeGroups.OrderBy(o => o.Group.ID))
                {
                    List<QuestionViewModel> questionViewModels = new List<QuestionViewModel>();
                    List<Question> groupQuestions = schemeQuestions.Where(f => f.Group.ID == item.Group.ID).ToList();
    
                    for (int i = 0; i < groupQuestions.Count; i++)
                    {
                        questionViewModels.Add(new QuestionViewModel(contentModel.Content) { Question = groupQuestions[i], Answer = new AnswerViewModel(contentModel.Content) { QuestionID = groupQuestions[i].ID } });
                    }
    
                    WizardStepViewModel wizardStepViewModel = new WizardStepViewModel(contentModel.Content)
                    {
                        GroupId = item.Group.ID,
                        GroupName = item.Group.GroupName,
                        Questions = questionViewModels,
                        WizardStep = wizardStep,
                        FinalWizardStep = schemeGroups.Count
                    };
    
                    foreach (var questionViewModel in wizardStepViewModel.Questions)
                    {
    
                    }
    
                    schemeSteps.Add(wizardStepViewModel);
                    wizardStep++;
                }
    
                schemeWizardStepsViewModel.Scheme = scheme;
                schemeWizardStepsViewModel.CurrentWizardStep = 1;
                schemeWizardStepsViewModel.Steps = schemeSteps;
    
                //Persist data here...
                Session["CurrentWizardStep"] = schemeWizardStepsViewModel.CurrentWizardStep;
                Session["SchemeWizardStepViewModel"] = schemeWizardStepsViewModel;
    
                return View("~/Views/quoteForm.cshtml", schemeWizardStepsViewModel);
    
            }
    
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult HandleWizardStepAction(WizardStepViewModel wizardStepViewModel, string submitButton)
            {
                //http://www.binaryintellect.net/articles/c69d78a3-21d7-416b-9d10-6b812a862778.aspx
                //https://stackoverflow.com/questions/442704/how-do-you-handle-multiple-submit-buttons-in-asp-net-mvc-framework
                switch (submitButton)
                {
                    case "Next":
                        return (MoveToNextWizardStep(wizardStepViewModel));
                    case "Previous":
                        return (MoveToPreviousWizardStep(wizardStepViewModel));
                    case "Finish":
                        return (FinishWizard(wizardStepViewModel));
                    default:
                        // If they've submitted the form without a submitButton, 
                        // just return the view again.
                        return (View());
                }
            }
    
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult MoveToNextWizardStep(WizardStepViewModel wizardStepViewModel)
            {
                SchemeWizardStepsViewModel schemeWizardStepsViewModel = (SchemeWizardStepsViewModel)Session["SchemeWizardStepViewModel"];
                return View("~/Views/quoteForm.cshtml", schemeWizardStepsViewModel);
            }
    
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult MoveToPreviousWizardStep(WizardStepViewModel wizardStepViewModel)
            {
                ModelState.Clear();
                SchemeWizardStepsViewModel schemeWizardStepsViewModel = (SchemeWizardStepsViewModel)Session["SchemeWizardStepViewModel"];
                return View("~/Views/quoteForm.cshtml", schemeWizardStepsViewModel);
            }
    
    
            [HttpPost]
            public ActionResult FinishWizard(WizardStepViewModel wizardStepViewModel)
            {
                return  View("~/Views/quoteForm.cshtml");
            }
    
        }
    }
    

    I am not inheriting from "surfacecontroller" and instead using "rendermvccontroller" due to if i used surface, I always faced errors about not being able to bind the models builder model to my custom model.

    Can anyone suggest where I am going wrong?

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies