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 302 posts 648 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 1081 posts 7319 karma points MVP 4x 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 302 posts 648 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 3223 posts 10887 karma points MVP 4x 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 302 posts 648 karma points
    Mar 23, 2016 @ 08:35
    Paul Sørensen
    0

    Hi Yes but it makes no difference /Thx

  • Dave Woestenborghs 3223 posts 10887 karma points MVP 4x 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 302 posts 648 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 3223 posts 10887 karma points MVP 4x 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 302 posts 648 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 3223 posts 10887 karma points MVP 4x 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 302 posts 648 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 3223 posts 10887 karma points MVP 4x 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 302 posts 648 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 3223 posts 10887 karma points MVP 4x 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 302 posts 648 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 3223 posts 10887 karma points MVP 4x 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 302 posts 648 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

Please Sign in or register to post replies

Write your reply to:

Draft