form to post to actionresult with kentico content based routing

lawrence whittemore asked on March 16, 2022 18:20

No idea how to word this question or if it is even a thing. I have a controller for a page type that uses content based routing. How would I call an action result from a form post

I have something this, <form method="post" action="~/Forum/ForumTopicAdd"> but it doesn't take in the current page information.

Hope that makes sense.

Recent Answers


Brenden Kehren answered on March 16, 2022 18:32

Assuming you're using the OOTB forms, you'd need to do one of the two things:

  1. Create a global handler to do your work after the form is submitted.
  2. Create the form manually and set your post to handle the work in the controller.

There could be other options but these are the 2 that come to mind.

0 votesVote for this answer Mark as a Correct answer

lawrence whittemore answered on March 16, 2022 18:44

So I am creating the form manually in a razor page. What I am getting stuck on is I want to call an action result from the controller created for that page type, (i don't know if that makes sense) I'm trying to build a basic message forum. I am working on creating a button to add a new topic to the forum. So i was thinking that I could do a post back to the current page I am on to create the new topic based on the form being filled out. But I am not sure how to post back to the current page and access the action result I created to add the new topic.

I know I can create my own routing and get the form to post to the controller I want, but I loose the current page the user is viewing, so I didn't know if there was a way to use the content based routing but still call the action result i was looking for.

Hope that makes sense.

0 votesVote for this answer Mark as a Correct answer

lawrence whittemore answered on March 16, 2022 19:49 (last edited on March 16, 2022 19:50)

I think i figured out what i was looking for, Not setting the action posts it back directly to the page i am on... Also, needed to call the action result Index.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on March 16, 2022 19:53

This makes more sense now. You can also use Form Tag Helpers for the form element.

0 votesVote for this answer Mark as a Correct answer

Trevor Fayas answered on March 17, 2022 23:36

Lawrence, what you may be looking for is a sort of Post-Redirect-Get (PRG) method of form submission.

Page (from content tree routing) submits to a controller (posts), that handles the submission, then redirects back to the original page (Get) with some of the form status intact.

We did that for the Baseline, you can reference the files and look at how we did the LogIn.cshtml and LogInController.cs, we also outline how to do this in the [PRG Post Redirect Get wiki page. It involves preserving the ModelState and View Model in the TempData which exists between requests and then restoring it.

0 votesVote for this answer Mark as a Correct answer

Trevor Fayas answered on March 17, 2022 23:39

Keep in mind, another, sometimes simpler method is to make your form AJAX, where it posts through an ajax call.

I wrote a taghelper to make a form ajax-able, it also hooks up the client side validation after. Just add "ajaxify-form" onto your form tag when this is in your solution and make sure your action result is a partial view of the form.

using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Threading.Tasks;

namespace KinderMorgan.Library.TagHelpers
{
[HtmlTargetElement("form", Attributes = "ajaxify-form")]
public class AjaxifyFormTagHelper : TagHelper
{
    // Just so it shows up
    public bool AjaxifyForm { get; set; } = true;
    public string AjaxifyFormErrorMessage { get; set; } = "An error occurred while submitting.";
    public string AjaxifyFormRedirectAfterSubmission { get; set; } = string.Empty;
    public AjaxifyFormTagHelper()
    {

    }
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        if (AjaxifyForm)
        {
            var randomID = Guid.NewGuid().ToString().Replace("-", "");
            output.PreElement.AppendHtml($"<div id=\"ajaxwrapper-{randomID}\">");

            // Adds loader, will need to use styling to hide/show when form appends ajax-submitting to form
            output.PreContent.AppendHtml(@"
                <div class=""ajax-submitting-overlay"">
                    <div class=""loader""></div>
                </div>");

            output.PostElement.AppendHtml($"</div>");
            output.PostElement.AppendHtml(@"<script type=""text/javascript"">
        function AjaxifyForm" + randomID + @"() {
            var formWrapper = document.getElementById('ajaxwrapper-" + randomID + @"');
            var form = formWrapper.getElementsByTagName('form')[0];
            var formSubmitTo = form.getAttribute('action');
            var formMethod = form.getAttribute('method');
            var alreadyRan = false;
            form.onsubmit = function() {
                var jQueryValidatorExists = typeof($) !== 'undefined' && typeof($.validator) !== 'undefined';
                var jQueryUnobtrusiveExists = jQueryValidatorExists && typeof($.validator.unobtrusive) !== 'undefined';
                if(jQueryValidatorExists) {
                    if(!$(form).valid()) {
                        return false;
                    };
                }
                var data = new FormData(form);
                if(!alreadyRan) {
                    alreadyRan = true;
                    form.classList.add('ajax-submitting');
                    fetch(formSubmitTo, {
                        method: formMethod,
                        body: data
                    }).then(response => {
                        return response.text();
                    }).then(function (html) {
                        formWrapper.innerHTML = html;
                        var newForms = formWrapper.getElementsByTagName('form');
                        if(newForms.length > 0) {
                            AjaxifyForm" + randomID + @"();
                            var newForm = newForms[0];
                            if(jQueryValidatorExists) {
                                var newFormjQuery = $(newForm);
                                if(jQueryUnobtrusiveExists) {
                                    $.validator.unobtrusive.parse(newFormjQuery);
                                    newFormjQuery.validate(newFormjQuery.data('unobtrusiveValidation').options);
                                } else {
                                    newFormjQuery.validate();
                                }
                            }
                            // Reset already ran
                            alreadyRan = false;
                        } else {
                            // No form, probably submitted properly, what next?
                            " + (!string.IsNullOrWhiteSpace(AjaxifyFormRedirectAfterSubmission) ? $"window.location = '{AjaxifyFormRedirectAfterSubmission}';" : "") + @"
                        }
                    }).catch(function (err) {
                        // There was an error
                        alert('" + AjaxifyFormErrorMessage + @"');
                    });
                }
                return false;
            }
        }
        AjaxifyForm" + randomID + @"();
    </script>");
        }
    }
}
}
1 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.