Copied to clipboard

Flag this post as spam?

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


  • Joe Dirte 21 posts 163 karma points
    Apr 04, 2017 @ 19:12
    Joe Dirte
    0

    Umbraco Field returns null in some cases

    Hey guys,

    Question over umbraco.field values.

    I have a page that contains a form in a partial. When this form is submitted it hits a surface controller and then returns a view.

    I have a link on the same page that takes a user to the same view but bypasses the partial form submission workflow.

    In the destination view I have field value that the user defines.

    When I access the destination view via the bypass button, the umbraco.field value is set and all is right in the world.

    When I go through the partial form submission workflow, the umbraco.field is null.

    I can set a field on the parent page and set recursive to true and everything works fine, so what gives? Any way to combat this behavior?

  • Jamie Pollock 174 posts 853 karma points c-trib
    Apr 04, 2017 @ 19:33
    Jamie Pollock
    0

    Hey Joe,
    Sorry to hear you're having problems. Would it be at all possible to provide some code snippets excluding any sensitive business logic. We don't necessarily need the whole thing just view and maybe some of the surfacecontroller wire up.

    Also, which version of Umbraco are you using?

    Thanks,
    Jamie

  • Joe Dirte 21 posts 163 karma points
    Apr 04, 2017 @ 19:49
    Joe Dirte
    0

    Using the latest and greatest version from nuget.

    public class FancySurfaceController : SurfaceController
    {
        [HttpPost]
        public ActionResult Submit(LocationModel someLocation)
        {
            someLocation.SetGeoCoord();
            ViewBag.SomeCollection = LocateSomething.GetSomethingInProximity(someLocation.SearchCenter);
            ViewBag.OriginalLocation = someLocation.InitialLocationInput;
    
            return View("~/Views/FindLocalThings.cshtml");
        }
    }
    
        @using Some.Extensions.Controllers
    @using ClientDependency.Core.Mvc
    @{
        Html.RequiresJs("/scripts/FindSomething.js");
    }
    @model Something.Extensions.Models.LocationModel
    @using (Html.BeginUmbracoForm<FancySurfaceController>("Submit"))
    {
        @Html.HiddenFor(m => m.Lat)
        @Html.HiddenFor(m => m.Lng);
        @Html.HiddenFor(m => m.InitialLocationInput);
    
    
        <input type="submit" id="submitLookup" style="display: none" />
    }
    

    Are the controller and partial.

    @{ Html.RenderPartial("~/Views/Partials/FindSomethingSearch.cshtml", new LookupModel());}
    

    Is the partial include on the origin page

    //works fine no matter the access point
        var foo = Umbraco.Field("numberOfDisplayedThings", recursive: true);
    
    //works from FindLocalThings page, but not when through surface controller
    //var foo1 = Umbraco.Field("numberOfDisplayedThings");
    
  • Jamie Pollock 174 posts 853 karma points c-trib
    Apr 04, 2017 @ 21:34
    Jamie Pollock
    0

    Hmm, I see. So it doesn't work while inside the surface controller?

    There's an overload for Umbraco.Field(IPublishedContent content, "numberOfDisplayedThings").

    What happens if you pass CurrentPage inUmbraco.Field(CurrentPage, "numberOfDisplayedThings")?

  • Joe Dirte 21 posts 163 karma points
    Apr 04, 2017 @ 21:58
    Joe Dirte
    0

    That results in an RTE Binder issue for ambiguous calls.

    The call is ambiguous between the following methods or properties: 'Umbraco.Web.UmbracoHelper.Field(string, string, string, string, string, bool, bool, bool, Umbraco.Web.RenderFieldCaseType, Umbraco.Web.RenderFieldEncodingType, bool, bool, string)' and 'Umbraco.Web.UmbracoHelper.Field(Umbraco.Core.Models.IPublishedContent, string, string, string, string, string, bool, bool, bool, Umbraco.Web.RenderFieldCaseType, Umbraco.Web.RenderFieldEncodingType, bool, bool, string)'

  • Joe Dirte 21 posts 163 karma points
    Apr 04, 2017 @ 22:16
    Joe Dirte
    0

    Actually going either workflow results in CurrentPage being null, which is why the overload is failing to bind.

    What would cause CurrentPage to be null though?

  • Joe Dirte 21 posts 163 karma points
    Apr 05, 2017 @ 13:15
    Joe Dirte
    0

    The following works for either workflow, but it feels a bit hacky.

        DynamicNode node = new DynamicNode(1112);
        var displayedThingCount = Convert.ToInt32(node.GetPropertyValue("numberOfDisplayedThings"));
    

    Any thoughts on the underlying cause?

  • Jamie Pollock 174 posts 853 karma points c-trib
    Apr 06, 2017 @ 03:06
    Jamie Pollock
    100

    Hey Joe,
    Sorry I've not responded. It's been a very busy day.

    That does look a bit hacky! ;)

    I noticed in your controller.

    [HttpPost]
    public ActionResult Submit(LocationModel someLocation)
    {
        return View("~/Views/FindLocalThings.cshtml");
    }
    

    post you return a View("~/Views/FindLocalThings.cshtml"); have you tried returning CurrentUmbracoPage(); or RedirectToCurrentUmbracoPage(); instead?

    I'm not sure if this is too far off your implementation but I recently built a contact form SurfaceController which may or may not solve your problem.

        using My.Website.Models;
        using My.Website.ViewModels;
        using System;
        using System.Linq;
        using System.Web.Mvc;
        using Umbraco.Web.Mvc;
    
        namespace My.Website.Controllers
        {
            public class ContactFormSurfaceController : SurfaceController
            {
                //This is the logic used when a request first hits the page
                [ChildActionOnly]
                public ActionResult Form()
                {
                    return PartialView("ContactForm", new ContactFormViewModel());
                }
    
                //This is the logic used when return CurrentUmbracoPage() is called
                [ChildActionOnly]
                [HttpPost]
                public ActionResult Form(ContactFormViewModel model)
                {
                    return PartialView("ContactForm", model);
                }
    
                [HttpPost]
                [ValidateAntiForgeryToken]
                public ActionResult Send(ContactFormViewModel model)
                {
                    if (ModelState.IsValid)
                    {
                        //Handle success with your own business logic
    
                        //Pass sent TempData to let the partial know it's been sent and hide the form
                        TempData["sent"] = true;
    
                        //Clear current form by redirecting to the current page
                        return RedirectToCurrentUmbracoPage();
                    }
    
                    //If it isn't valid return the current umbraco page with the current model
                    return CurrentUmbracoPage();
                }
            }        
        }
    

    And for the partial view:

    @model My.Website.ViewModels.ContactFormViewModel
    @{ 
        var sent = TempData["sent"];
        var isSent = sent != null && (sent as bool?) == true;
    }
    
    @if (isSent)
    {
        <p class="title is-3">Message sent</p>
        <p>Thank you!</p>
    }
    else
    {
        using (Html.BeginUmbracoForm<My.Website.Controllers.ContactFormSurfaceController>("Send", FormMethod.Post, new { @class = "form" }))
        {
            <fieldset>
                <legend class="title is-3">Get In Touch</legend>    
    
                <!-- a bunch of input fields which are bound using @Html.EditorFor(model => model.MyPropertyName) -->
    
                <div class="field">
                    <p class="control">
                        <button class="button is-primary" type="submit">Contact Us!</button>
                    </p>
                </div>
            </fieldset>
            @Html.AntiForgeryToken()
        }
    }
    

    And finally to include to the partial on the page simply use: @Html.Action("Form", "ContactFormSurface")

    Admittedly I'm not using any Umbraco properties in my partial view, however I did use some Umbraco properties within the handle success part of the logic and that worked fine.

    I hope this helped and it wasn't too far off tangent.

    Thanks,
    Jamie

  • Joe Dirte 21 posts 163 karma points
    Apr 06, 2017 @ 14:32
    Joe Dirte
    0

    Hey Jamie,

    I'm not going to get a chance to circle back to this until this weekend, but I'll give it a go and let you know!

    Thanks

  • Jamie Pollock 174 posts 853 karma points c-trib
    Apr 06, 2017 @ 15:14
    Jamie Pollock
    0

    No worries, mate. Have a good one and I hope we get this solved for you :)

  • Joe Dirte 21 posts 163 karma points
    Apr 09, 2017 @ 18:23
    Joe Dirte
    1

    +10 points

  • Jamie Pollock 174 posts 853 karma points c-trib
    Apr 09, 2017 @ 19:30
    Jamie Pollock
    0

    Ace :)

Please Sign in or register to post replies

Write your reply to:

Draft