A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Custom MVC form ignoring HttpPost in controller? Returning 404

Vote:
 

Hey all,

I'm creating a simple address editor for our site's customers.  Or so I thought.  Basically what I seem to be running into is the HttpPost ActionResult in my controller seems to be ignored.  I suspect it has something to do with EpiServer's routing.  When I submit my form, I'm getting the standard .net 404 error page, and if I view source on it, I notice this message commented out at the bottom:

So cutting to the chase, here's my relevant code:

Controller:

using CMS.Models.Pages;
using CMS.Models.ViewModels;
using EdmundOptics.Data.Core.Repositories;
using EdmundOptics.Data.Entity;
using EPiServer;
using EPiServer.ServiceLocation;
using EPiServer.Web;
using Microsoft.AspNet.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace CMS.Controllers
{
    public class AddressBookController : Controller
    {
        public IContentLoader _icontentLoader;
        public SitePageData _sitePageData;

        public AddressBookController()
        {
            _icontentLoader = ServiceLocator.Current.GetInstance();
            _sitePageData = _icontentLoader.Get(SiteDefinition.Current.StartPage);
        }

        [Authorize]
        [HttpGet]
        public ActionResult AddressCreate(int? addressId)
        {
            var currentPage = _sitePageData;
            ViewBag.CurrentPage = currentPage;
            ViewBag.EditButtonText = "Add New Address";
            AddressCreateViewModel vm = new AddressCreateViewModel();
            if (addressId != null)
            {

                ViewBag.EditButtonText = "Edit Address";

                AddressBookRepository addressBookRepository = new AddressBookRepository();
                string userId = User.Identity.GetUserId();
                var customerAddresses = addressBookRepository.Addresses_List_ByUserId(userId);


                foreach (CustomerAddress address in customerAddresses)
                {
                    if (address.AddressId == addressId)
                    {
                        vm.AddressId = address.AddressId;
                        vm.AddressName = address.AddressName;
                        vm.FirstName = address.FirstName;
                        vm.LastName = address.LastName;
                        vm.Company = address.Company;
                        vm.JobTitle = address.JobTitle;
                        vm.Phone = address.Phone;
                        vm.PhoneExt = address.PhoneExt;
                        vm.Fax = address.Fax;
                        vm.Country = address.CountryId;
                        vm.CountryName = address.CountryName;
                        vm.AddressLine1 = address.AddressLine1;
                        vm.AddressLine2 = address.AddressLine2;
                        vm.AddressLine3 = address.AddressLine3;
                        vm.AddressLine4 = address.AddressLine4;
                        vm.City = address.City;
                        vm.State = address.StateId;
                        vm.Region = address.RegionName;
                        vm.PostalCode = address.PostalCode;
                        vm.PrimaryShipping = address.PrimaryShipping;
                        vm.PrimaryBilling = address.PrimaryBilling;

                        ViewData.Model = vm;
                    }
                }
            }
            return View(vm);
        }

        
        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public ActionResult AddressCreatePost(AddressCreateViewModel vm)
        {
            var currentPage = _sitePageData;
            ViewBag.CurrentPage = currentPage;
            string userId = User.Identity.GetUserId();

            if (ModelState.IsValid)
            {
                AddressBookRepository addressBookRepository = new AddressBookRepository();
                CustomerAddress customerAddress = addressBookRepository.Address_Get(vm.AddressId);

                var isNew = customerAddress == null;

                if (isNew)
                {
                    int? newAddressId = addressBookRepository.Address_Insert(
                        userId,
                        vm.AddressName,
                        vm.FirstName,
                        vm.LastName,
                        vm.Company,
                        vm.JobTitle,
                        vm.Phone,
                        vm.PhoneExt,
                        vm.Fax,
                        vm.Country,
                        vm.AddressLine1,
                        vm.AddressLine2,
                        vm.AddressLine3,
                        vm.AddressLine4,
                        vm.City,
                        vm.State,
                        vm.Region,
                        vm.PostalCode,
                        vm.PrimaryShipping,
                        vm.PrimaryBilling
                        );

                    vm.AddressId = newAddressId;
                }
                else
                {
                    addressBookRepository.Address_Update(
                        vm.AddressId,
                        vm.AddressName,
                        vm.FirstName,
                        vm.LastName,
                        vm.Company,
                        vm.JobTitle,
                        vm.Phone,
                        vm.PhoneExt,
                        vm.Fax,
                        vm.Country,
                        vm.AddressLine1,
                        vm.AddressLine2,
                        vm.AddressLine3,
                        vm.AddressLine4,
                        vm.City,
                        vm.State,
                        vm.Region,
                        vm.PostalCode,
                        vm.PrimaryShipping,
                        vm.PrimaryBilling
                        );
                }

                if (vm.PrimaryBilling)
                {
                    addressBookRepository.Address_UpdatePrimary(1, vm.AddressId);
                }

                if (vm.PrimaryShipping)
                {
                    addressBookRepository.Address_UpdatePrimary(0, vm.AddressId);
                }

                return Redirect("/address-book/");
            }
            else
            {
                return View("AddressCreate", vm);
            }
        }

    }
}



Here is the form in the view:

    @using (Html.BeginForm("AddressCreatePost", "address-book", FormMethod.Post, new { @class = "bootstrap-frm" }))
    {

//Form Fields are all here



}

And finally here is my route configured in /Business/Initialization/RouteConfig.cs:

            routes.MapRoute(
                name: "AddressBook",
                url: "address-book/{action}",
                defaults: new { controller = "AddressBook", action = "Index", param = UrlParameter.Optional }
                );

And in case it's significant, here is where the routes are called in Global.asax.cs:

        protected override void RegisterRoutes(RouteCollection routes)
        {
            base.RegisterRoutes(routes);
            CMS.Business.Initialization.RouteConfig.RegisterRoutes(routes);

        }

Important observations so far:  It seems like for some reason this is only happening on using the [HttpPost] attribute.  I have other ActionResults in that controller that I call async with no problems at all.  And in a similar controller I have async Tasks using HttpPost attribute that work just fine as well.  It seems to be just these particular circumstances that aren't working and its driving me up a wall :-)

Thank you in advance for any help you can offer.

#188316
Edited, Feb 19, 2018 16:45
Vote:
 

I forgot to mention, I tried putting a breakpoint inside the httppost actionresult but it didn't seem to even get hit at all.  At least not inside it.

#188317
Feb 19, 2018 16:48
Vote:
 

Hey all,

I resolved the issue.  As it turns out, there was an old 301 redirect rule in our webconfig that was trying to add a trailing slash to the end of the form action.  Once it did that, it went through as a get instead of a post.  I commented out that rule and everything works perfectly now.  Thank you!

#188318
Feb 19, 2018 19:37
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.