Copied to clipboard

Flag this post as spam?

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


  • Paul Sørensen 304 posts 650 karma points
    Mar 22, 2016 @ 22:52
    Paul Sørensen
    0

    BeginUmbracoForm renders wrong action

    Hi I'm using BeginUmbracoForm and suddenly it does not render the action using the surfacecontroller and the specified action like this

    form action="/umbraco/Surface/Tour/Register" method="post"

    as expected from this

    @using (Html.BeginUmbracoForm<TourController>("Register"))
    

    It renders the original url to the current for the current document.

    When I change it to this

    @using (Html.BeginForm("Register", "Tour"))
    

    the correct action is rendered, but then I miss the UmbracoContext in the Register implementation.

    If I insert another controller that works in another view it also renders the wrong action.

    /Paul S

  • Marc Goodson 2157 posts 14434 karma points MVP 9x c-trib
    Mar 23, 2016 @ 07:52
    Marc Goodson
    0

    Hi Paul

    Does the form post back to your surface controller if you submit it ?

    the routing values are encoded in the ufprt hidden field, which is generated by Html.BeginUmbracoForm

    If you have at look at the source for RenderRouteHandler:

    https://github.com/umbraco/Umbraco-CMS/blob/4a101786972bb591bb5d22acd043cc9f9da267ed/src/Umbraco.Web/Mvc/RenderRouteHandler.cs

    you can see where the hidden field is being read, decoded and the route is resolved...

    regards

    Marc

  • Paul Sørensen 304 posts 650 karma points
    Mar 23, 2016 @ 08:39
    Paul Sørensen
    0

    Hi

    I does not post back to my controller. I have get methods on my controller which get hit but not this post method.

    I can see the field if I inspect the html, but isn't the important thing here what's in the action tag. It's wrong because it just shows

    ntw - I just upgraded to 7.4.2 but don't think that's the problem since it works in other views on my site

    /Paul S

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Mar 23, 2016 @ 07:59
    Dave Woestenborghs
    0

    Hi Paul,

    Have you tried :

    @using (Html.BeginUmbracoForm("Register","Tour"))
    

    Dave

  • Paul Sørensen 304 posts 650 karma points
    Mar 23, 2016 @ 08:35
    Paul Sørensen
    0

    Hi Yes but it makes no difference /Thx

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Mar 23, 2016 @ 09:36
    Dave Woestenborghs
    0

    What do you see in the action tag of the rendered form ?

    Dave

  • Paul Sørensen 304 posts 650 karma points
    Mar 23, 2016 @ 11:35
    Paul Sørensen
    0

    Hi

    This is my form tag

    <form action="/kalender/tilmeldning-til-ture-og-matcher/" enctype="multipart/form-data" method="post">
    

    This matches the url in my content.

    /Paul S

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Mar 23, 2016 @ 11:38
    Dave Woestenborghs
    0

    Hi Paul,

    Can you show the code from your controller ?

    And maybe the output of the generated form. That way we can look where it goes wrong.

    Dave

  • Paul Sørensen 304 posts 650 karma points
    Mar 23, 2016 @ 19:41
    Paul Sørensen
    0

    Hi Dave

    The controller is here

    namespace MensSection.Controllers
    {
        public class TourController : BaseSurfaceController, IRenderMvcController
        {
    
            public ActionResult Index(RenderModel m)
            {
                Log.Info("TourController:Index called");
                var model = new TourViewModel();
    
                DateTime start = new DateTime(DateTime.Now.Year - 1, 1, 1);
    
                List<Caddie.Data.Dto.Tour> dtos = MyRepository.GetSeasonTours(base.Season, DateTime.Now).ToList();
                model.Tours = AutoMapper.Mapper.Map<IEnumerable<ItemModel>>(dtos);
                if (this.TempData["tourId"] != null)
                {
                    model.TourId = Convert.ToInt32(this.TempData["tourId"]);
                }
                else
                    model.TourId = model.Tours.ToList().FirstOrDefault().Id;
    
                var member = base.CurrentMember;
                model.IsLoggedIn = (member != null);
                model.IsRegistrered = IsRegistrered(model.TourId);
    
                return View("Tour", model);
            }
    
            public ActionResult GetTourDetails(int tourId)
            {
                Log.Info("TourController:GetTourDetail called");
                var model = new TourDetailsViewModel();
    
                this.TempData["tourId"] = tourId;
                List<Caddie.Data.Dto.TourPlayer> dtos = MyRepository.GetTourPlayers(tourId).ToList();
                model.Players = AutoMapper.Mapper.Map<List<TourPlayerModel>>(dtos);
    
                Caddie.Data.Dto.Tour dto = MyRepository.GetTour(tourId);
                model.Tour = AutoMapper.Mapper.Map<TourModel>(dto);
                try
                {
                    model.Tour.SponsorLogoUrl = Umbraco.Media(model.Tour.SponsorLogoId).Url;
                }
                catch (Exception e)
                {
                    Log.ErrorFormat("Finding Sponsor URL failed: {0}", e.Message);
                }
    
                if (string.IsNullOrEmpty(model.Tour.SponsorLogoUrl))
                {
                    model.Tour.SponsorLogoUrl = "/media/725/munkebjerg.png";
                    model.Tour.Sponsor = "Munkebjerg Hotel";
                }
                return PartialView("TourDetails", model);
            }
    
            [HttpPost]
            public ActionResult Register(TourViewModel model)
            {
                Log.Info("TourController:Register called");
                if (CurrentMember != null)
                {
                    MyRepository.TourChangeRegistration(model.TourId, CurrentMemberVgcNo, CurrentMember.Name);
                }
                return CurrentUmbracoPage(); 
            }        
    }
    

    The BaseSurfaceController is here

    namespace MensSection.Controllers
    {
        public class BaseSurfaceController : SurfaceController
        {
            protected static readonly log4net.ILog Log =
                log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    
           #region CurrentMember
            private Umbraco.Core.Models.IMember member = null;
            private int memberId = -1;
            private void GetCurrentMemberInfo()
            {
                if (memberId < 0)
                {
                    memberId = 0;
                    var memberShipHelper = new Umbraco.Web.Security.MembershipHelper(base.UmbracoContext);
                    memberId = memberShipHelper.GetCurrentMemberId();
                    member = ApplicationContext.Current.Services.MemberService.GetById(CurrentMemberId);
                }
            }
            public Umbraco.Core.Models.IMember CurrentMember
            {
                get
                {
                    GetCurrentMemberInfo();
                    return member;
                }
            }
            public int CurrentMemberId
            {
                get
                {
                    GetCurrentMemberInfo();
                    return memberId;
                }
            }
            #endregion
    
            #region MyRepository
            private Caddie.Data.Repository repos;
            protected Caddie.Data.Repository MyRepository
            {
                get
                {
                    if (null == repos)
                        repos = new Caddie.Data.Repository();
                    return repos;
                }
            }
    
            #endregion
    
            #region debug
            protected static void DebugListChildren(global::Umbraco.Core.Models.IPublishedContent root)
            {
                string s;
                foreach (var x in root.Children) //.where(x => x.documenttypealias == "newsarea").firstordefault();
                {
                    s = x.DocumentTypeAlias;
                    s = x.Name;
                }
            }
            #endregion
        }
    }
    

    The output of the generated form

    <form action="/kalender/tilmeldning-til-ture-og-matcher/" enctype="multipart/form-data" method="post"><input id="SelectedText" name="SelectedText" type="hidden" value="Weekendtur til Tyskland"><input id="TourId" name="TourId" type="hidden" value="81">        <div class="form-group row">
                <div class="col-sm-6 dropdown" id="inputTour">
                    <button class="btn btn-primary" id="selectButton" data-toggle="dropdown" aria-expanded="false">Weekendtur til Tyskland&nbsp;<span class="caret"></span></button>
                    <ul class="dropdown-menu scrollable-menu" id="ulGenres">
                            <li>
                                <a href="#" data-pdsa-dropdown-val="81">Weekendtur til Tyskland</a>
                            </li>
                            <li>
                                <a href="#" data-pdsa-dropdown-val="85">Afslutningsmatch, gunstart</a>
                            </li>
                    </ul>
                </div>
                <div class="col-sm-6">
                  <button type="submit" name="Command" value="Register" class="btn btn-primary">Tilmeld / Afmeld</button>
                </div>
            </div>
    <input name="ufprt" type="hidden" value="36218E7961487A2B2E554C9FC46541D995054D026A4E80237DED31CBB99634847F6CD5365FD019A7EBDD7347FE827E4E124A36531B43FEF4651FDA03DA87CC7B06CA62BFC9874F194F75899F83DAF34F489339A5F5019D308AF141396EB83DFC5250FD089C02F09124EAD7791AD9E0482D0D5BE04C3A744923D110E29FA820E6"></form>
    

    and the Tour template

    @using MensSection.Models
    @inherits Umbraco.Web.Mvc.UmbracoViewPage<TourViewModel>
    @{
        Layout = "CalendarLayout.cshtml";
    }
    @section Main
    {
    <div class="col-xs-12">
        @using (Html.BeginUmbracoForm("Register", "Tour"))
        {
            string btnClass = "btn btn-primary";
            if (!Model.IsLoggedIn)
            { btnClass += " disabled"; }
    
            @Html.HiddenFor(m => m.SelectedText)
            @Html.HiddenFor(m => m.TourId)
            <div class="form-group row">
                <div class="col-sm-6 dropdown" id="inputTour">
                    <button class="btn btn-primary"
                            id="selectButton"
                            data-toggle="dropdown">
                        Arrangement
                        <span class="caret"></span>
                    </button>
                    <ul class="dropdown-menu scrollable-menu" id="ulGenres">
                        @foreach (var item in Model.Tours)
                        {
                            <li>
                                <a href="#" data-pdsa-dropdown-val="@item.Id">@item.StringValue</a>
                            </li>
                        }
                    </ul>
                </div>
                <div class="col-sm-6">
                  <button type="submit" name="Command" value="Register" class="@btnClass">Tilmeld / Afmeld</button>
                </div>
            </div>
            if(!Model.IsLoggedIn)
            {
                <span class="text-warning">Du skal være logget ind for at kunne tilmelde dig til arrangementer</span>
            }
    
        }
        <div id="Details" class=""></div>
    </div>
    }
    
    @section script
    {
    
    
    
    
    <script type="text/javascript">
            function DataLoad() {
                var id = $("#TourId").val();
                $("#Details").load('/umbraco/Surface/Tour/GetTourDetails?tourId=' + id);
            }
            $(document).ready(function () {
                $("#ulGenres li a").on("click", function () {
                    // Get text from anchor tag
                    var id = $(this).data('pdsa-dropdown-val');
                    $("#TourId").val(id);
                    // Add text and caret to the Select button
                    var text = $(this).text();
                    $("#selectButton").html(text + '&nbsp;<span class="caret"></span>');
                    // Put text into hidden field from model
                    $("#SelectedText").val(text);
                    DataLoad();
                });
                var id = $("#TourId").val();
                $("#ulGenres li a").filter("[pdsa-dropdown-val= " + id + "]").trigger("click");
            });
        </script>
    
    
    
    
    }
    

    /

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Mar 23, 2016 @ 20:26
    Dave Woestenborghs
    0

    hi Paul,

    All looks great at first glance. Maybe this a wild suggestion, but is your HttpPost attribute on the action from the System.Web.Mvc namespace. There is also one in the System.Net.Http namespace meant for WebApi controllers ?

    Dave

  • Paul Sørensen 304 posts 650 karma points
    Mar 24, 2016 @ 00:10
    Paul Sørensen
    0

    Hi Dave

    It is

    using System;
    using System.Collections.Generic;
    using System.Web.Mvc;
    using Umbraco.Web.Models;
    using Umbraco.Web.Mvc;
    using MensSection.Models;
    

    /Paul S

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Mar 24, 2016 @ 07:10
    Dave Woestenborghs
    0

    Hi Paul,

    That seams okay. Can you try to remove the model parameter from the post action to see if it get's hit then ? I had troubles sometimes in the past the model binding on post didn't work and that caused my post action not being hit.

    Dave

  • Paul Sørensen 304 posts 650 karma points
    Mar 24, 2016 @ 10:54
    Paul Sørensen
    0

    Hi Dave It makes no difference

        [HttpPost]
        public ActionResult Register()
        {
            Log.Info("TourController:Register called");
            //if (CurrentMember != null)
            //{
            //    MyRepository.TourChangeRegistration(model.TourId, CurrentMemberVgcNo, CurrentMember.Name);
            //}
            return CurrentUmbracoPage(); 
        }
    

    also tried to change back to

    @using (Html.BeginUmbracoForm<MensSection.Controllers.TourController>("Register"))
    

    /Paul S

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Mar 24, 2016 @ 11:20
    Dave Woestenborghs
    0

    Hi Paul,

    Also running out of id's here. Do you have perhaps setup some custom routing that would interfere. Or a IIS redirect ?

    Dave

  • Paul Sørensen 304 posts 650 karma points
    Mar 25, 2016 @ 18:59
    Paul Sørensen
    0

    Hi Sometimes it helps leaving things for a some time and then try again. The Register now gets called if I leave out the parameter.

    With the parameter in the method I get

    Cannot bind source type Umbraco.Web.Models.RenderModel to model type MensSection.Models.TourViewModel.
    

    I don't understand where the rendermodel comes from because it's a TourViewModel. It inherits from RenderModel - is that the reason?

    If I change the parameter to a RenderModel then the method get's called - but then I don't have my custom properties.

    /Paul S

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Mar 26, 2016 @ 08:59
    Dave Woestenborghs
    100

    Hi Paul,

    I think the cause is that your model inherits from RenderModel. The name says it actually it is used for rendering.

    I never inherit my models from RenderModel.

    Dave

  • Paul Sørensen 304 posts 650 karma points
    Mar 26, 2016 @ 22:34
    Paul Sørensen
    0

    Hi Dave I used your advice together with a more or less rewrite - now it works - thanks for your help.

    Guess lesson learned is not to use RenderModel with SurfaceControllers

    /Paul S

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies