Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
Experience Sitecore! | Helix project, MVC routing and the form posting back to controller. Part 2 - Creating a form

Experience Sitecore!

Martin Miles on Sitecore

Helix project, MVC routing and the form posting back to controller. Part 2 - Creating a form

In previous part, we created a test feature, as a part of a Helix-based solution. We also created a page and rendering and wired it together. So, now it's time to create a form.

As a start, let's create a controller, as it is referenced from rendering definition item:

namespace YourSolution.Feature.Test.Controllers
{
    public class TestController : Controller
    {
        public ActionResult Test()
        {
            return View();
        }
    }
}

Then create corresponding Razor view..

@using Sitecore.Mvc.Configuration
@model YourSolution.Feature.Test.Models.TestModel

@using (Html.BeginRouteForm(MvcSettings.SitecoreRouteName, FormMethod.Post))
{
    @Html.LabelFor(x => x.FirstName)
    @Html.TextBoxFor(x => x.FirstName)
    
    @Html.LabelFor(x => x.LastName)
    @Html.TextBoxFor(x => x.LastName)

    @Html.LabelFor(x => x.Email)
    @Html.TextBoxFor(x => x.Email)
}


.. and model that represents our form, to be passed between controller and view:

namespace YourSolution.Feature.Test.Models
{
    public class TestModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
    }
}

As we are working with a project outside of webroot, we need to use gulp in order to copy this view into corresponding folder on the website (or you may copy that manually), same for the feature DLL.

After refreshing browser you will see the view. Obviously, when trying to hit "Submit" button - nothing happens as there's no POST controller action method. So let's add the one:

namespace YourSolution.Feature.Test.Controllers
{
    public class TestController : Controller
    {
        public ActionResult Test()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Test(TestModel loginInfo)
        {
            // do something
        }
    }
}

Still not there... why? Let's troubleshoot that. First thing to do is to find out where form does POST to. In webinspector, it shows:

  <form action="/test" method="post"> ... </form>

So far so good - that looks correct (form POSTs to itself). But how /test URL corresponds to YourSolution.Feature.Test.Controllers.Test() method of YourSolution.Feature.Test feature project?

That's where routing comes into a play. As you know, feature is just a single project that is built into individual DLL and is deployed into /bin folder of project webroot along with other libraries. So how do we wire up /test with that particular method?

We apply config patch Feature.Test.config in order to add a pipeline processor right before the one that initializes MVC routes.


  
    
      
        
      
    
  

After running gulp configuration task this patch will be put into YourSolution/Website/App_Config/Include/Features folder along with custom configuration include file patches for other feature modules. Corresponding processor will be the following:

using System.Web.Mvc;
using System.Web.Routing;
using Sitecore.Pipelines;

namespace YourSolution.Feature.Test.Pipelines
{
    public class RegisterWebApiRoutes
    {
        public void Process(PipelineArgs args)
        {
            RouteTable.Routes.MapRoute("Feature.Test.Api", "api/test/{action}", new { controller = "Test" });
        }
    }
}

Finally the last bit to make routing work - modify _ViewStart.schtml view file on the project level. Here is it:

@{
    Layout = (this.ViewContext.IsChildAction) || (this.ViewContext.RouteData.Values.ContainsKey("scIsFallThrough") && 
        Convert.ToBoolean(this.ViewContext.RouteData.Values["scIsFallThrough"])) ? null : "~/Views/Shared/_Layout.cshtml";
}

If you have done everything correctly, after gulp'ing your assets into web folder and refreshing the page in browser, you'll see a form similar to the one below:


That's it! Now the form is fully functional and POSTs to a controller, however in order to make things even better - let's apply form validation.

References:

    Sitecore Helix Documentation


blog comments powered by Disqus