Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Stephen 6 posts 96 karma points
    Nov 20, 2019 @ 14:56
    Stephen
    0

    Ajax submission to one of my Surface Controllers has stopped working

    I have a website using Umbraco 8 which uses Ajax in a slightly awkward way, which worked fine up until recently but has unexpectedly stopped working (and nothing I've been working on lately is in the same area as it, so it would be odd if I'd accidentally broken it myself). Here's the section of the View (this is actually a Partial, nested inside a main View that provides header/menu/etc, with EventList being another partial that gives the actual results)

     @using (Ajax.BeginForm("EventListAll", "EventSubItem", null, new AjaxOptions
    {
        HttpMethod = "POST",
        InsertionMode = InsertionMode.Replace,
        UpdateTargetId = "event-results"
    }, new { @style="height:auto; background-color:white" }))
    {
        <div id="d_Events_Filter" class="d_Row">
            <div class="d_Filter_Btn">
                <img src="~/Images/Events/Events_bookings.png" />
                <span>My Bookings</span>
                <span>Under Construction</span>
            </div>
            <div class="d_Filter_Btn">
                <input type="submit" src="~/Images/Events/Events_list.png" name="btnAll" value="Full List" style="color:transparent;background:transparent;" />
                <img src="~/Images/Events/Events_list.png" />
                <span>List</span>
            </div>
            <div class="d_Filter_Btn">
                <input type="submit" src="~/Images/Events/Events_month.png" name="btnMonth" value="Month" style="color:transparent;background:transparent;" />
                <img src="~/Images/Events/Events_month.png" />
                <span>Month</span>
            </div>
            <div class="d_Filter_Btn">
                <input type="submit" src="~/Images/Events/Events_week.png" name="btnWeek" value="Week" style="color:transparent;background:transparent;" />
                <img src="~/Images/Events/Events_week.png" />
                <span>Week</span>
            </div>
            <div class="d_Filter_Btn">
                <img src="~/Images/Events/Events_map.png" />
                <span>Map</span>
                <span>Under Construction</span>
            </div>
        </div>
        @Html.HiddenFor(m => m.searchtype)
        <div id="d_Events_Search_Wrap" class="d_Row">
            <div id="d_Events_Search">
                <div id="d_Events_Textboxes">
                    @Html.DropDownListFor(m => m.SelectedCategory, new SelectList(Model.Categories,"Select a category"), new { @id="dl_Categories" })
                    @Html.DropDownListFor(m => m.SelectedRegion, new SelectList(Model.Regions, "RegionID", "RegionName", "Select a region"), new { @id="dl_Regions" })
                    @Html.TextBoxFor(m => m.SearchLocation, new { @id="tb_Location" })
                    @Html.TextBoxFor(m => m.SearchKeyWords, new { @id="tb_Keywords" })
                    <input type="submit" id="btn_Events_Search" name="btnSearch" class="hl_More_Feed_Button" value="FIND EVENTS" />
                </div>
            </div>
        </div>
        <div id="event-results">
            @{ Html.RenderAction("EventList", "EventSubItem"); }
        </div>
    }
    

    In the Surface Controller I have a series of actions like so

    [HttpPost]
    [AcceptParameter(Name = "btnAll")]
    public ActionResult EventListAll()
    {
        return EventListFilter("Full List");
    }
    
    [HttpPost]
    [AcceptParameter(Name = "btnMonth")]
    [ActionName("EventListAll")]
    public ActionResult EventListMonth()
    {
        return EventListFilter("Month");
    }
    
    [HttpPost]
    [AcceptParameter(Name = "btnWeek")]
    [ActionName("EventListAll")]
    public ActionResult EventListWeek()
    {
        return EventListFilter("Week");
    }
    

    AcceptParameter is a custom ActionMethodSelectorAttribute I swiped from Nicholas Westby's answer in an older thread on this forum, which gets round the fact that Umbraco refuses to accept that a form might submit to multiple actions, and has the following code:

    // Namespaces.
    using System;
    using System.Web.Mvc;
    
    
    /// <summary>
    /// When this attribute decorates an action method, that action method will
    /// only be routed to if the specified request parameter matches the specified value.
    /// </summary>
    public class AcceptParameterAttribute : ActionMethodSelectorAttribute
    {
    
        #region Properties
    
        /// <summary>
        /// The name of the request parameter.
        /// </summary>
        public string Name { get; set; }
    
    
        /// <summary>
        /// The value of the request parameter. Optional.
        /// </summary>
        /// <remarks>
        /// If unspecified, the check will just be to see if the value exists rather than
        /// if the value matches something in particular.
        /// </remarks>
        public string Value { get; set; }
    
        #endregion
    
    
        #region Methods
    
        /// <summary>
        /// Indicates whether or not this request contains the specified name/value.
        /// </summary>
        public override bool IsValidForRequest(
            ControllerContext controllerContext,
            System.Reflection.MethodInfo methodInfo)
        {
            var req = controllerContext.RequestContext.HttpContext.Request;
            bool valid;
            if (string.IsNullOrEmpty(this.Value))
            {
                valid = !string.IsNullOrEmpty(req.Form[this.Name]);
            }
            else
            {
                valid = string.Equals(req.Form[this.Name], this.Value,
                    StringComparison.InvariantCultureIgnoreCase);
            }
            return valid;
        }
    
        #endregion
    
    }
    

    I have an outside requirement here that my page has these "Month", "Week" etc buttons that provide different filtering of the list of events, so I'm kinda stuck with the "multiple buttons controlling the same set of results" setup (particularly, since I have to have a dynamic Search, I can't just pre-render all three result lists and have the buttons secretly tab between them).

    Sorry for the avalanche of code there...

    The thing is, this house of cards all worked totally fine until very recently, when I tried to test the existing functionality in anticipation of making some changes and found that I was getting 404 errors returned from my Surface Controller on every button click. All four buttons, including the one that's connecting to the 'real' EventListAll action, now just give me a 404 result instead.

    The especially baffling thing to me is that our Staging site, which has a version of the code that's about two months old but in this particular respect is identical code-wise, is still running totally fine. Has there been an update to Umbraco in the last two months that might have broken this? Or does anyone have any other advice?

  • Stephen 6 posts 96 karma points
    Nov 27, 2019 @ 15:09
    Stephen
    0

    Update on this: I still haven't found a solution, but I've narrowed down the problem. My Request.Form is coming up empty, even though I've checked using Firebug and Fiddler that the data is being sent from the browser. And there's not a second GET or second POST being made, as far as I can see.

    Does anyone know why Umbraco might be discarding Request.Form data?

Please Sign in or register to post replies

Write your reply to:

Draft