Copied to clipboard

Flag this post as spam?

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


  • Yoadd 6 posts 76 karma points
    Jul 17, 2022 @ 14:21
    Yoadd
    0

    Return List of IPublishedContent from Controller

    Hi I'm new to Umbraco and would appreciate help with the following scenario - my content tree is structured as below:

    • Home Page

      • Projects

        • Project 1
        • Project 2

    This is my Controller:

    public class ProjectsController : UmbracoApiController
        {
            private readonly UmbracoHelper _umbracoHelper;
    
            public ProjectsController(UmbracoHelper umbracoHelper)
            {
    
                _umbracoHelper = umbracoHelper;
            }
    
            [HttpGet]
            public List<IPublishedContent> FilterProjects(string? product, string? style, string? space, string? architect, string? installer)
            {
                // get 'projects' node
                var node = _umbracoHelper.Content(Guid.Parse("017b9615-4809-4f96-9c8c-212ecb5ce18d"));
                if (node is null) return null;
    
                List<IPublishedContent> returnedChildren = new List<IPublishedContent>();
    
                foreach (IPublishedContent _child in node.Children)
                {
                    bool matched = false;
    
                    var products = _child.GetProperty("products").GetValue() as IEnumerable<IPublishedContent>;
                    if (products != null && products.Any())
                    {
                        foreach (var _product in products)
                        {
                            if (product != null && product.Split(',').Contains(_product.Name.Trim()))
                            {
                                matched = true;
                            }
    
                            if(style != null && style.Split(',').Contains(_product.Parent.Name.Trim()))
                            {
                                matched = true;
                            }
    
                        }
                    }
    
                    var spaces = _child.GetProperty("space").GetValue() as IEnumerable<string>;
                    if(spaces != null && spaces.Any())
                    {
                        foreach(string _space in spaces)
                        {
                            if (space != null && space.Split(',').Contains(_space.Trim()))
                            {
                                matched = true;
                            }
                        }
                    }
    
                    var architects = _child.GetProperty("architect").GetValue() as IEnumerable<string>;
                    if (architects != null && architects.Any())
                    {
                        foreach (string _architect in architects)
                        {
                            if (architect != null && architect.Split(',').Contains(_architect.Trim()))
                            { 
                                matched = true;
                            }
                        }
                    }
    
                    var installers = _child.GetProperty("installer").GetValue() as IEnumerable<string>;
                    if (installers != null && installers.Any())
                    {
                        foreach (string _installer in installers)
                        {
                            if (installer != null && installer.Split(',').Contains(_installer.Trim()))
                            {
                                matched = true;
                            }
                        }
                    }
    
                    if (matched)
                    {
                        returnedChildren.Add(_child);
                    }
                }
    
    
                return returnedChildren;
            }
        }
    

    I'm comparing strings because most of the properties in my Document Type are of Tags type (with the exception of products which is of Treepicker type)

    This however throws an exception stating JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.

    It seems to me that the whole Content Tree is being returned instead of just the filtered Project nodes.

    Any help would be very much appreciated.

  • Andrey Karandashov 23 posts 215 karma points c-trib
    Jul 18, 2022 @ 06:30
    Andrey Karandashov
    0

    I think it's impossible to return IPublishedContent from your controller, but you always can convert it into your own model and return it which is easier for you.

  • Yoadd 6 posts 76 karma points
    Jul 20, 2022 @ 12:35
    Yoadd
    0

    Hi, thank you for the answer.

    I don't think converting it to a model will help in my case, because what I am trying to do is show the user a projects gallery.

    Please let me clarify - my intention was to show the user a view consisting of several dropdown filters (and a "search" button), along with a projects gallery.

    Let's say, the first 10 Project nodes under Projects node.

    The user may choose to filter said gallery so that when he/she presses the search button, the view is re-rendered with only the filtered projects shown.

    Since I'm new to Umbraco , perhaps using the ApiController is not the right choice, since I don't want to return just JSON from the controller, I want the view to be able to re-render itself, so to say.

    I understand there are 2 more types of controllers: RenderController and SurfaceController, maybe one of them is a better choice?

    Let me also provide a snippet of my current View:

    @using Umbraco.Cms.Core.Models;
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ContentModels.AllProjects>
    @using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
    @using Umbraco.Cms.Core.Services;
    @using Umbraco.Cms.Core.PropertyEditors;
    @using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
    
    @inject IDataTypeService DataTypeService;
    
    @{
        Layout = "master.cshtml";
    
       @* get the projects node under Content *@
        var projects = Umbraco.Content(Guid.Parse("017b9615-4809-4f96-9c8c-212ecb5ce18d")).ChildrenOfType("project").Where(x => x.IsVisible());
    }
    
    @{
        if (projects != null && projects.Any())
        {
            <section class="all-projects-gallery">
                <div class="container">
                   @{foreach(var project in projects) {...}}
                </div>
            </section>
        }
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft