Umbraco 7 Submitting Forms using post and get.

In Umbraco, we have 2 ways to submit form data, we can use either RenderMvcController or SurfaceController, ideally, you would use the Surface Controller to post a contact form or user login details and RenderMvcController for a search form. 

This blog will show how you can use both ways to submit a form and also includes Html.BeginUmbracoForm which you will find only allows both post and get methods.

To run this example, I have created a helper class library, a model class library and a core class library.

The core class library is where the controllers are, I prefer this way of coding as I believe that the UI should not contain any controllers.

The helper class has the test data and the model class contains the model.

Below is how the site structure is laid out.

Test Data.

The test data just has hardcoded data about pets and I add the data to a list.

using System.Collections.Generic;
namespace Web.Model.TestData
{
    public class TypeOfPets
    {
        public TypeOfPets(string petTypeId, string petType)
        {
            PetTypeId   = petTypeId;
            PetType     = petType;
        }
        public string PetTypeId { get;}
        public string PetType   { get;}
    }
    public static class TestSearchData
    {
            public static IEnumerable DogList()
            {
                List typesOfPet = new List
                {
                    new TypeOfPets("dog", "German Shepherd"),
                    new TypeOfPets("dog", "Husky"),
                    new TypeOfPets("cat", "Russian Blue"),
                    new TypeOfPets("fish", "Goldfish")
                };
                return typesOfPet;
            }
    }
}

Helper Code.

The helper class get the URL of the search results page, I'm using a content picker in the CMS for this, the reason for this is what would happen if you had a doctype that had multiple pages, it would be very difficult to know which doctype is the page we require.

Also what would happen if the client changed the name of doctype or deleted it and created a new one, using the content picker, the client just needs to update the picker with the new doctype and we are ready to go.

More than likely the search page would be a dedicated doctype so the need to use a content picker would not be required, but I'm just showing how it can be used.

using System.Linq;
using Umbraco.Core.Models;
using Umbraco.Web;
namespace Web.Helper.SearchHelper
{
    public static class SearchHelper
    {
        public static string SearchPageUrl()
        {
            var umbContent          = UmbracoAssignedContentHelper.PageContentForIEnumerableIPublishedContent("homePage");
            string searchPageUrl    = umbContent.First().GetPropertyValue("searchPage").Url;
            return searchPageUrl;
        }
        public static string SearchPageSurfaceUrl()
        {
            var umbContent = UmbracoAssignedContentHelper.PageContentForIEnumerableIPublishedContent("homePage");
            string searchPageUrl = umbContent.First().GetPropertyValue("searchSurface").Url;
            return searchPageUrl;
        }
    }
}

View Model Code.

The view model is used to display the data, one uses RenderModel as I use RnnderMvcController and the other is a plain SurfaceController.

using System.Collections.Generic;
using System.Globalization;
using Umbraco.Core.Models;
using Umbraco.Web.Models;
using Web.Model.TestData;
namespace Web.Model.SearchViewModel
{
    public class SearchPageRenderMvcControllerViewModel : RenderModel
    {
        public SearchPageRenderMvcControllerViewModel(IPublishedContent content, CultureInfo culture) : base(content, culture)
        {
        }
        public SearchPageRenderMvcControllerViewModel(IPublishedContent content) : base(content)
        {
        }
        public IEnumerable DisplaySearchResult { get; set; }
    }
    public class SearchPageSurfaceControllerViewModel
    {
        public IEnumerable DisplaySearchResult { get; set; }
    }
}
Controller Code.

The controller filters the search results and has both get and post ActionResults.

using System;
using System.Linq;
using System.Web.Mvc;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Web.Model.SearchViewModel;
using Web.Model.TestData;
namespace Web.Core.Controllers
{
    public class SearchFormController : RenderMvcController
    {
        [HttpGet]
        public ActionResult SearchForm(RenderModel objModel, string q)
        {
            var queryResult = TestSearchData.DogList().Where(x => string.Equals(x.PetTypeId, q, StringComparison.CurrentCultureIgnoreCase));
            var model = new SearchPageRenderMvcControllerViewModel(objModel.Content)
            {
                DisplaySearchResult = queryResult
            };
            return CurrentTemplate(model);
        }
        [HttpPost]
        public ActionResult SearchForm(RenderModel objModel, string q, string dummyParam)
        {
            var queryResult = TestSearchData.DogList().Where(x => string.Equals(x.PetTypeId, q, StringComparison.CurrentCultureIgnoreCase));
            var model = new SearchPageRenderMvcControllerViewModel(objModel.Content)
            {
                DisplaySearchResult = queryResult
            };
            return CurrentTemplate(model);
        }
    }
    public class SearchFormNotRouteController : SurfaceController
    {
        [HttpGet]
        public ActionResult SearchForm(string q)
        {
            var queryResult = TestSearchData.DogList().Where(x=>string.Equals(x.PetTypeId, q, StringComparison.CurrentCultureIgnoreCase));
            var model = new SearchPageSurfaceControllerViewModel
            {
                DisplaySearchResult = queryResult
            };
            return PartialView("~/Views/Partials/pvSurfaceSearch.cshtml",model);
        }
        [HttpPost]
        public ActionResult SearchForm(string q, string dummyParam)
        {
            var queryResult = TestSearchData.DogList().Where(x => string.Equals(x.PetTypeId, q, StringComparison.CurrentCultureIgnoreCase));
            var model = new SearchPageSurfaceControllerViewModel
            {
                DisplaySearchResult = queryResult
            };
            return PartialView("~/Views/Partials/pvSurfaceSearch.cshtml", model);
        }
        [HttpPost]
        public ActionResult SearchFormUmbraco(string q)
        {
            var queryResult = TestSearchData.DogList().Where(x => string.Equals(x.PetTypeId, q, StringComparison.CurrentCultureIgnoreCase));
            var model = new SearchPageSurfaceControllerViewModel
            {
                DisplaySearchResult = queryResult
            };
            return PartialView("~/Views/Partials/pvSurfaceSearch.cshtml", model);
        }
    }
}
Home Page.

If you notice the action for the form gets its value from the search helper which simply returns the URL, the last 2 forms use Html.BeginUmbracoForm, with the last form having a get method and you, will notice the URL also contains the hidden field 'ufprt'

@using Web.Helper.SearchHelper
@inherits UmbracoViewPage
@{
    Layout = "Layout.cshtml";
}
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <h1>Search Via RenderMvcController method is GET</h1>
            <form method="get" action="@SearchHelper.SearchPageUrl()" name="RenderMvc" id="RenderMvc">
                <div class="form-group">
                    <input class="form-control" type="text" name="q" id="q" placeholder="Enter keyword 'dog' or 'cat' or 'fish'" />
                </div>
                <br />
                <button class="btn btn-info" type="submit">Search</button>
            </form>
            <h1>Search Via RenderMvcController method is Post</h1>
            <form method="post" action="@SearchHelper.SearchPageUrl()" name="RenderMvcPost" id="RenderMvcPost">
                <div class="form-group">
                    <input class="form-control" type="text" name="q" id="q" placeholder="Enter keyword 'dog' or 'cat' or 'fish'" />
                </div>
                <br />
                <button class="btn btn-success" type="submit">Search</button>
            </form>
            <hr />
            <h1>Search Via SurfaceController method is GET</h1>
            <form method="get" action="@SearchHelper.SearchPageSurfaceUrl()" name="Surface" id="Surface">
                <div class="form-group">
                    <input class="form-control" type="text" name="q" id="q" placeholder="Enter keyword 'dog' or 'cat' or 'fish'" />
                </div>
                <br />
                <button class="btn btn-dark" type="submit">Search</button>
            </form>
            <hr />
            <h1>Search Via SurfaceController method is Post</h1>
            <form method="post" action="@SearchHelper.SearchPageSurfaceUrl()" name="SurfacePost" id="SurfacePost">
                <div class="form-group">
                    <input class="form-control" type="text" name="q" id="q" placeholder="Enter keyword 'dog' or 'cat' or 'fish'" />
                </div>
                <br />
                <button class="btn btn-danger" type="submit">Search</button>
            </form>
            <hr/>
            <h2>Search Via SurfaceController method is Post using Html.BeginUmbracoForm</h2>
            @using (Html.BeginUmbracoForm("SearchFormUmbraco", "SearchFormNotRoute"))
            {
                <div class="form-group">
                    <input class="form-control" type="text" name="q" id="q" placeholder="Enter keyword 'dog' or 'cat' or 'fish'"/>
                </div>
            <br />
            <button class="btn btn-danger" type="submit">Search</button>
            }
 <hr/>
            <h3>Search Via SurfaceController method is Get using Html.BeginUmbracoForm</h3>
            @using (Html.BeginUmbracoForm("SearchFormUmbraco", "SearchFormNotRoute", FormMethod.Get))
            {
                <div class="form-group">
                    <input class="form-control" type="text" name="q" id="q" placeholder="Enter keyword 'dog' or 'cat' or 'fish'"/>
                </div>
                <br />
                <button class="btn btn-danger" type="submit">Search</button>
            }
        </div>
    </div>
</div>
Summary.

Thank you for reading this blog about submitting forms in Umbraco 7, I hope you found it helpful.