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.

Test data
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<TypeOfPets> DogList()
            {
                List<TypeOfPets> typesOfPet = new List<TypeOfPets>
                {
                    new TypeOfPets("dog", "German Shepherd"),
                    new TypeOfPets("dog", "Husky"),
                    new TypeOfPets("cat", "Russian Blue"),
                    new TypeOfPets("fish", "Goldfish")
                };
                return typesOfPet;
            }
    }
}

Helper

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.

Helper Code
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<IPublishedContent>("searchPage").Url;

            return searchPageUrl;
        }

        public static string SearchPageSurfaceUrl()
        {
            var umbContent = UmbracoAssignedContentHelper.PageContentForIEnumerableIPublishedContent("homePage");
            string searchPageUrl = umbContent.First().GetPropertyValue<IPublishedContent>("searchSurface").Url;

            return searchPageUrl;
        }
    }
}

View Model

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

View Model Code
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<TypeOfPets> DisplaySearchResult { get; set; }
    }

    public class SearchPageSurfaceControllerViewModel
    {
        public IEnumerable<TypeOfPets> DisplaySearchResult { get; set; }
    }
}

Controller

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

Controller Code
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 uses Html.BeginUmbracoForm, with the last form having a get method and you will notice the URL also contains the hidden field 'ufprt'


Home Page Code
@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>

I hope you found this code helpful, if so, please leave a comment below.

Blog Form

 Please complete the required fields (*required)

 *
*