Model binding and dependency injection

This article will describe how to inject data in controller actions.

Model binders

When executing an action on a controller information about the requested page, category or product is needed. The model binder will find information about the request and assign that to the parameter in the action method.

The parameter type is important, for example if you have the parameter Page pageParam the binder will try to parse the parameter as a Page, if you send in a page id (Guid) with the name pageParam to this request the page with this id will be loaded into the parameter.

For automatic mapping of current entity (baseproduct, page etc.) from the input parameters in the request the word current should be used in the name, for example Page currentPage. When the parameter name starts with current the parsing of input parameters in the request is ignored, instead the parameter is only assigned from the values that is extracted from the url-parsing.

Model binders can be used for the following entities:

  • Litium.Foundation.Modules.CMS.Pages.Page
  • Litium.Foundation.Modules.CMS.WebSites.WebSite
  • Litium.Studio.Builders.CMS.PageTypeDefinition
  • Litium.Products.BaseProduct
  • Litium.Products.Category
  • Litium.Products.Variant

Dependency injection

Dependency injection is used to feed the controller with different types of services when it is constructed. Examples of services that can be used is BaseProductService, VariantService and CategoryService together with special parameters that are listed below, which are not real services but will be injected in the constructor of the controller.

  • Litium.Foundation.Security.SecurityToken - to get access to the security token for the user that makes the request.
  • Litium.Foundation.Modules.CMS.Routing.RoutePath - to get access to parsed information from the request, for example if https (IsSecureConnection) or if request is in administration mode (IsInAdministration)
  • Litium.Foundation.Modules.ECommerce.ShoppingCarts.Cart - to get access to the shopping cart for the user that makes the request.

Below is a controller with examples of using model binders and dependency injection:

using System.Web.Mvc;
using JetBrains.Annotations;
using Litium.Accelerator.Definitions.PageTypes;
using Litium.Accelerator.Mvc.ViewModels;
using Litium.Accelerator.Services;
using Litium.Foundation.Modules.CMS.Pages;
using Litium.Foundation.Modules.CMS.Routing;
using Litium.Foundation.Modules.CMS.WebSites;
using Litium.Foundation.Security;
using Litium.Products;
using Litium.Runtime.AutoMapper;
using Litium.Web.Mvc;

namespace Litium.Accelerator.Mvc.Controllers.Pages
{
  public class StartpageController : LitiumController
  {
  private readonly RoutePath _routePath;
  private readonly ISectionService _sectionService;
  private readonly SecurityToken _token;

  public StartpageController(ISectionService sectionService, RoutePath routePath,
    SecurityToken token)
  {
    // All registered classes are avaliable to resolve in the controller 
    // constructor, a few examples are illustrated here.

    _sectionService = sectionService;
    _routePath = routePath;
    _token = token;
  }

  [HttpPost]
  public JsonResult ExampleAjaxCall(StartPage currentPageDefinition, Page pageById,
    Page currentWhateverNameHere, BaseProduct productById, WebSite currentWebSite)
  {
    // This action is called from the javascript example below and use a 
    // combination of injection and model binding.

    return Json(new
    {
    // pageById is mapped by its datatype, the value passed from javascript 
    // is a Guid but since the parameter is of type 
    // Litium.Foundation.Modules.CMS.Pages.Page the model binder will
    // map it to the page represented by the id.
    page = pageById.ShortName,
    // The currentWhateverNameHere parameter is mapped to the currentpage which 
    // is the page of the called url, in this case the root (startpage). 
    // The parametername illustrates that it is the combination of the keyword 
    // 'current' and the datatype 'page' that triggers the mapping. 
    // So although it is recommended for clarity to name the parameter 'currentPage' 
    // it is not required.
    currentPage = currentWhateverNameHere.ShortName,
    // RoutePath object contains information about the current route and request, 
    // for example querystring and if the page is being viewed in Litium backoffice
    // (IsInAdministration)
    isInAdministration = _routePath.IsInAdministration,
    // The injected user token contains information about the current user
    user = _token.User.DisplayName,
    // Product by id works the same way as 'pageById' described above
    product = productById.Localizations.CurrentCulture.Name
    });
  }

  [HttpGet]
  [PageProperties(typeof(StartPage))]
  [PageTemplate(typeof(StartPage), "~/Site/Images/startpage.png", Name = "StartPage1")]
  public ActionResult Index([NotNull] StartPage currentPageDefinition,
    WebSite currentWebSite)
  {
    // An action can be mapped to a specific page template, the action 
    // makes use of the items injected in te constructor and also the page definition
    // and current website through model binding. The StartPage class inherits 
    // Litium.Studio.Builders.CMS.PageTypeDefinition allowing it to be bound.

    var startPageModel = currentPageDefinition.MapTo<StartPageViewModel>();
    startPageModel.Sections =
    _sectionService.GetSectionsData(currentPageDefinition.CurrentBasePage);

    return View(startPageModel);
  }
  }
}

The following script makes a POST call to the ExampleAjaxCall action of the controller:

function ajaxExample() {
    $.ajax({
        type: 'POST',
        // Since the action is on the Startpage controller in this case 
        // the url to the controller is the site-root, "/", 
        // then as described above a dot is used to set selected action.
        url: '/.ExampleAjaxCall',
        // Pass data to the action my matching parametername and datatype
        data: {
            'pageById': 'df174051-de29-41e6-a57b-8316081b9855',
            'productById': '4d2c259f-037f-4837-a339-16c84df6ea01'
        }
    }).done(function (data) {
        console.log(data);
        // Outputs:
        // currentPage: "Startsida"
        // isInAdministration: false
        // page: "Om oss"
        // product: "Skrivplatta"
        // user: "Anonymous user"
    });
}

 

 

 

 

 

 

Is this page helpful?
Thank you for your feedback!