Skip to content

Intercepting requests with your own controller and form posts

Simon Yohannes edited this page Jan 16, 2020 · 9 revisions

puck relies on on a catch all route in the Startup.cs file. you can intercept requests by adding a new route before the puck catch all route or optionally you can use attribute routing on your controller.

let's say you have Register form at the path /members/register, you will need to make a controller that inherits from puck.core.Controllers.BaseController with a Register action:

public class RegisterController : BaseController
{
    [HttpPost]
    [Route("members/register")]
    public ActionResult Register(RegisterModel model) {
        if (ModelState.IsValid) {
            //handle post
            Response.Redirect("/members/register/success");
        }
        //if invalid, return current puck page
        ViewBag.RegisterModel = model;
        return base.Puck();
    }
}

as you can see, there is a Register action with a route attribute to handle the form post. if the post is successful, you might want to redirect to a success page and if the model is invalid, you might want to return the current page. as you can see, the RegisterModel is put in the ViewBag when returning the current puck page, and when in your view you can pass the RegisterModel to a partial which will handle displaying the form.

Get current ViewModel from your controller action

if you've intercepted a page with your controller action you can grab the page's ViewModel by doing this:

var currentNode = QueryHelper<Page>.Current();

Type conditional request hijacking

By default, there is a catch-all endpoint mapped to the HomeController Index action. The code for this mapping is in Startup.cs:

endpoints.MapControllerRoute(
   name: "default",
   pattern: "{**path}"
   ,defaults: new { controller = "Home", action = "Index"}
);

HomeController inherits from puck.core.Controllers.BaseController and if you look at the Index action:

public IActionResult Index()
{
    return base.Puck();
}

all it does is call the inherited Puck action which will get the current page and render a view. if you wan't to hijack the request based on the Type of the page being rendered, you can do the following:

public IActionResult Index()
{
        var result = base.Puck();
        var viewResult = result as ViewResult;
        if (viewResult != null)
        {
            if (viewResult.Model != null) {
               var model = viewResult.Model as BaseModel;
               if (model.GetType() == typeof(Page)) {
                   return Content("Hello World!");
               }
            }
        }
        return result;
}

the above code will return "Hello World!" for pages of type Page but will otherwise return the usual view.