Currenct context model is null on POST

Vote:
 

I'm posting a form to a regular controller and all of the properties are populated except for the currentContext variable.  The currentContext varialble contains the product for the cms page.  I'm new to EpiServer and I'm not sure if I'm descrbing this correctly.

When the Index action is called the currentContext is populated and the page is displayed fine.  But when I post to the AddToCart method the currentContext is null. 

Please see the code below:

TestProductController.cs

        [HttpGet]
        public ActionResult Index(TestProduct currentContent, string entryCode = "", int count = 0, string sessionKey = "") 
        {
            var viewModel = _viewModelFactory.Create(currentContent, entryCode);
            viewModel.ItemCount += count;

            viewModel.Session = sessionKey == "" ? Guid.NewGuid().ToString() : sessionKey;

            return View(viewModel);
        }

        [HttpPost]
        public ActionResult AddToCart(TestProduct currentContent, string session, string code) 
        {
            var pageRouteHelper = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<EPiServer.Web.Routing.IPageRouteHelper>();
            var page = pageRouteHelper.Page;

            _viewModelFactory.AddToCart(currentContent, session, code);

            return RedirectToAction("Index", new { entryCode = code, count = 1, sessionKey = session });

        }

Index.cshtml


@model Cms.Web.CommerceArea.TestProduct.TestProductViewModel

@using (Html.BeginForm("AddToCart", "TestProduct", new { area = "commercearea" }, FormMethod.Post ))
{
    @Html.HiddenFor(x => x.Session)
    @Html.Hidden("code", Model.Variation.Code)
<div>
    Product Name:@Html.PropertyFor(x => x.Product.Name)
</div>
<div>
    Variation Name: @Html.PropertyFor(x => x.Variation.Name)
</div>
<div>
    Sku: @Html.PropertyFor(x => x.Variation.Code)
</div>
    <div>
        Cart Count: @Html.PropertyFor(x => x.ItemCount)
    </div>
    <div>
        <button type="submit" role="button">Add to Cart</button>
    </div>
}

Any help would be greatly appreciated.

Thank you

#261146
Aug 26, 2021 22:17
Vote:
 

Hi Kevin

It can be a little tricky to get form posts right with Episerver content.

To post the form to the URL of the page (with AddToCart appended), you may need to remove the controller name from you BeginForm method call. Maybe you will also need to add the content link your route values.

Something like this:

@using (Html.BeginForm("AddToCart", null, new { area = "commercearea", node = Mode.Variation.ContentLink }, FormMethod.Post ))

Let me know how it works out.

#261187
Aug 27, 2021 15:08
Vote:
 

Hi Stepan,

Thank you for the help but the currentConent variable is still null. public ActionResult AddToCart(TestProduct currentContent, string session, string code) 

The TestProduct won't bind during the call.

#261188
Aug 27, 2021 15:26
Stefan Holm Olsen - Aug 27, 2021 15:27
Has the URL of the post request changed? If so, to what?
Vote:
 

No the URL hasn't changed.  I made the changes you suggested above but the currentContent isn't instantiating.

#261190
Aug 27, 2021 15:31
Stefan Holm Olsen - Aug 27, 2021 15:48
How does the URL look right now?
Kevin Fox - Aug 27, 2021 15:54
Not sure which url so I'll give you what I have.
The browser url is https://localhost:44300/en/Test-Product-en.aspx/
The url within the form is /commercearea/TestProduct/AddToCart.
Stefan Holm Olsen - Aug 27, 2021 16:05
Looks like you have a custom MVC route to control the commercearea part. This may interfere with the solution I posted.
Kevin Fox - Aug 27, 2021 16:11
I figured that was a possible issue. But the post won't find the controller if I don't include the area.
Forgot to mention to you earlier the node = Mode.Variation.ContentLink gave me a 'Mode does not exist in the current context' error.
Stefan Holm Olsen - Aug 27, 2021 16:14
Sorry, "Mode" should be "Model". Thanks to my browser auto-correct.
The intention is to pass the ContentReference of the product/variant to the URL generation method. This way the URL will be the full path of the content, plus the action name.
Kevin Fox - Aug 27, 2021 16:22
Okay that seems to work. I'm new to EpiServer and haven't had a lot of training so I've been doing a lot o trial and error.
Thank you again.
Stefan Holm Olsen - Aug 27, 2021 16:27
You are welcome. Episerver/Optimizely is a big platform, with lots of things to learn. Feel free to ask in the forums.
Kevin Fox - Aug 27, 2021 16:34
One more question.
Is there a setting/configuration that can be set within the initialization/set up that will make this happen on a post without adding the setting currentContent = Model.Product.ContentLink to every form ?
Stefan Holm Olsen - Aug 27, 2021 16:40
In short: no such setting.
But you could create your own HTML Helper extension to capture the current content link and pass to the built-in BeginForm method (like a method override).
But in the end, repeating this part just ends up being easier.
Kevin Fox - Aug 27, 2021 16:41
Okay. Thank you again for your help.
Vote:
 

Hi Kevin,

Could you share the complete controller code instead of just sharing the methods?

#261277
Edited, Aug 29, 2021 14:48
Vote:
 

Hi Sanjay,

namespace Cms.Web.CommerceArea.TestProduct.Controllers
{
    public class TestProductController : ContentController<Cms.Web.CommerceArea.TestProduct.Models.TestProduct>
    {
        private readonly TestProductEntryViewModelFactory _viewModelFactory;

        public TestProductController(TestProductEntryViewModelFactory viewModelFactory)
        {
            _viewModelFactory = viewModelFactory;
        }

        [HttpGet]
        public ActionResult Index(Cms.Web.CommerceArea.TestProduct.Models.TestProduct currentContent, string entryCode = "", int count = 0, string sessionKey = "")
        {
            var viewModel = _viewModelFactory.Create(currentContent, entryCode);
            viewModel.ItemCount += count;

            viewModel.Session = sessionKey == "" ? Guid.NewGuid().ToString() : sessionKey; // TEMP - Until session is put in place

            return View(viewModel);
        }

        [HttpPost]
        public ActionResult AddToCart(Cms.Web.CommerceArea.TestProduct.Models.TestProduct currentContent, string session, string code, string itemGuid)
        {
            _viewModelFactory.AddToCart(currentContent, session, itemGuid);

            return RedirectToAction("Index", new { currentContent = currentContent, entryCode = code, count = 1, sessionKey = session });

        }
    }
}

#261315
Aug 30, 2021 14:00
Vote:
 

Could you check the Cms.Web.CommerceArea.TestProduct.Models.TestProduct is inherited from ProductContent content type such as ?

Cms.Web.CommerceArea.TestProduct.Models.TestProduct : ProductContent

#261352
Aug 31, 2021 8:46
Vote:
 

Hi,

It is a quite old post, but do not know if you ever found the problem? We have seen this issue when your Post action is not using MVC HttpPost. Please ensure you are using [System.Web.Mvc.HttpPost] not [System.Web.Http.HttpPost].

~ Sujit

#264722
Oct 07, 2021 17:25
* 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.