How to call custom action in BlockController and redirect back to Index?

Vote:
 

I have block controller and custom action for filtering data after I filter the data I want to redirect back to the Index with the filtered data and render the block. How can I do this? Currently im redirecting back to "/" however I want to redirect to where the current block is. I tried Redirect(nameof(Index)) and I get 404.

#264094
Edited, Sep 29, 2021 9:14
Vote:
 

Hey Kiril, this blog post might be useful for what you are trying to achieve... Retrieving absolute url of current page on any page or block (optimizely.com)

#264129
Sep 29, 2021 15:05
Vote:
 

Hi Kiril,

This sounds very similar to an issue I had with getting standard MVC forms to work on a block.  You may want to post back to the block's controller, but that controller doesn't have a concept of which page the block is currently hosted.  I solved this by doing the following:

  1. Using a custom view model for the block, this view model included the content reference for the hosting page by using IPageRouteHelper.Page.ContentLink.  The IPageRouteHelper gives you a way to retrieve the page and language thread for the currently requested page.
  2. Passing the contentlink for the current page back as part of the model being passed back into the HttpPost action on the block controller.
  3. Saving the state of the submit model during the post action.
  4. Redirecting back to the page
  5. Loading the state of the submit model during the subsequent get action for the block
using System.Web.Mvc;

using EPiServer.Core;
using EPiServer.Web.Mvc;
using EPiServer.Web.Routing;

public class FormBlockController : BlockController<FormBlock>
{
	private readonly IPageRouteHelper _pageRouteHelper;

	public FormBlockController(IPageRouteHelper pageRouteHelper)
	{
		_pageRouteHelper = pageRouteHelper;
	}

	public override ActionResult Index(FormBlock currentContent)
	{
		var blockReference = (currentContent as IContent)?.ContentLink;
		var hadForm = LoadModelState(blockReference);
		var formSubmitModel = GetFormSubmitModel();
		var model = new FormBlockViewModel
		{
			CurrentPageReference = _pageRouteHelper.Page.ContentLink
		};

		if (ModelState.IsValid && hadForm)
		{
			// Do Submit state stuff
		}

		return PartialView("~/Views/Shared/Blocks/FormBlock.cshtml", model);
	}

	[HttpPost]
	public ActionResult Submit(FormSubmitModel formModel)
	{
		SaveModelState(formModel.CurrentBlockReference);

		return RedirectToAction("Index", new { node = formModel.CurrentPageReference, language = formModel.CurrentLanguage });
	}

	private FormSubmitModel GetFormSubmitModel()
	{
		return new FormSubmitModel
		{
			PropOne = GetAttemptedValue(nameof(FormSubmitModel.PropOne))
		};
	}

	private string GetAttemptedValue(string modelStateKey)
	{
		if (ModelState != null && ModelState.ContainsKey(modelStateKey))
		{
			return ModelState[modelStateKey].Value.AttemptedValue;
		}

		return string.Empty;
	}

	private void SaveModelState(ContentReference blockReference)
	{
		TempData[StateKey(blockReference)] = ViewData.ModelState;
	}

	private bool LoadModelState(ContentReference blockReference)
	{
		var key = StateKey(blockReference);
		var hadFormModelState = false;

		if (TempData.ContainsKey(key) && TempData[key] is ModelStateDictionary modelState)
		{
			ViewData.ModelState.Merge(modelState);
			TempData.Remove(key);
			hadFormModelState = true;
		}

		return hadFormModelState;
	}

	private string StateKey(ContentReference blockReference)
	{
		var blockId = blockReference?.ID ?? -1;

		return $"FormBlock_{blockId}";
	}
}
#264266
Oct 01, 2021 7:51
Vote:
 

Hi Kiril

The latest version of the v11 CMS UI has a new service called CurrentContentContext which allows you to work out the current content so would allow you to work out what page is rendering your block. 

There is a nice blog about it here: https://world.optimizely.com/blogs/bartosz-sekula/dates/2021/9/how-to-resolve-current-content-context/ 

David

#264271
Oct 01, 2021 10:11
Stotty - Oct 01, 2021 10:38
Ooh nice! I'll aim to use that in future :)
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.