Copied to clipboard

Flag this post as spam?

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


  • Patrick 33 posts 82 karma points
    Jul 13, 2015 @ 11:55
    Patrick
    0

    UmbracoApiController Model alternative

    I am struggeling with the following issue. In my cshtml file i have the following code:

    var uniqueMateriaal = Model.Children.Where(where).DescendantsOrSelf("Product").Select(x => x.GetPropertyValue("materiaal")).Distinct().OrderBy(z => z);
    

    Now I would like to move this line within a UmbracoApiController, however this does not recognize the model. I allready tried to retrieve the same by accessing the page first with

    Umbraco.Content(nodeId);
    

    In this case the lambda expressions won't get accepted. Do I have to cast it or is there another solution?

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Jul 13, 2015 @ 13:17
    Sebastiaan Janssen
    0

    Umbraco.Content is of type dynamic so you get no lambda's there. I think what you're looking for is Umbraco.TypedContent

  • Patrick 33 posts 82 karma points
    Jul 13, 2015 @ 14:53
    Patrick
    0

    Hi Sebastiaan,

    Thanks for responding, but when I change Model with Umbraco.TypedContent(nodeId) I cannot perform a where filter on it's children.

  • Anders Bjerner 487 posts 2989 karma points MVP 7x admin c-trib
    Jul 13, 2015 @ 15:06
    Anders Bjerner
    0

    Hi Patrick,

    Do you have an example of your lambda expressions? It should still work, so there might just be a tiny thing that you need to change.

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Jul 13, 2015 @ 15:10
    Sebastiaan Janssen
    0

    Not sure exactly what you're doing or what your where variable is, but I was hinting at the solution being something like this:

    var uniqueMateriaal = Umbraco.TypedContent(UmbracoContext.PageId.Value).Children.Where(where).DescendantsOrSelf("Product").Select(x => x.GetPropertyValue("materiaal")).Distinct().OrderBy(z => z);
    
  • Patrick 33 posts 82 karma points
    Jul 13, 2015 @ 19:01
    Patrick
    0

    I am using the where-statement to filter the collection. I've stripped the code to specify it some more:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Umbraco.Web.WebApi;
    using Umbraco;
    
    namespace Dts.Controllers
    {
        public class ZoekController : UmbracoApiController
        {
            [System.Web.Http.HttpGet]
            public string getResult(int nodeId, string kleurgroep, string materiaal, string vorm, string formaat)
            {
                string returnValue = "test";
                string where = "Visible";
    
                var uniqueMateriaal = Umbraco.TypedContent(nodeId).Children.Where(where).DescendantsOrSelf("Product").Select(x => x.GetPropertyValue("materiaal")).Distinct().OrderBy(z => z);
    
                return returnValue;
            }
        }
    }
    

    So I want to filter the uniqeMateriaal collection to be at least visible and in the final version I will add some more filters to the where-string throught the parameters. However your hint did'nt help, I hope this makes it a little more clear. It's a first attempt at this kind of sollution through a controller, so forgive me if I've got the wrong starting point.

  • Anders Bjerner 487 posts 2989 karma points MVP 7x admin c-trib
    Jul 13, 2015 @ 19:36
    Anders Bjerner
    0

    It should compile if you change the line to:

    var uniqueMateriaal = Umbraco.TypedContent(nodeId).Children.Where(x => x.IsVisible()).DescendantsOrSelf("Product").Select(x => x.GetPropertyValue("materiaal")).Distinct().OrderBy(z => z);
    
  • Patrick 33 posts 82 karma points
    Jul 14, 2015 @ 05:49
    Patrick
    0

    I am afraid it does not compile. It trips over x.IsVisible() and gives the following error:

    'Umbraco.Core.Models.IPublishedContent' does not contain a definition for 'IsVisible' and no extension method 'IsVisible' accepting a first argument of type 'Umbraco.Core.Models.IPublishedContent' could be found (are you missing a using directive or an assembly reference?)

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Jul 14, 2015 @ 06:12
    Sebastiaan Janssen
    0

    Make sure to have the following usings in your class:

    using System.Linq;
    using Umbraco.Web;
    using Umbraco.Web.Mvc;
    

    Especially Umbraco.Web is important as that's where the IsVisible extension method lives.

    Tip: Try ReSharper out, it gives you hints about missing usings. :)

  • Patrick 33 posts 82 karma points
    Jul 14, 2015 @ 06:38
    Patrick
    0

    Ah that's it, thanks Sebastaan! Only one slight problem left, x => x.GetPropertyValue("materiaal") doesn't seem to work anymore. If I change it in x => x.Name it still works. Any suggestions?

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Jul 14, 2015 @ 07:20
    Sebastiaan Janssen
    0

    Not sure what you mean? How does it not work?

    Maybe try to change it to x => x.GetPropertyValue<string>("materiaal")?

    Or just break it up into smaller pieces to see what goes wrong and to inspect the collection you're getting.

    var products = Umbraco.TypedContent(1234).Children.Where(x => x.IsVisible()).DescendantsOrSelf("Product");
    var materials = products.Select(x => x.GetPropertyValue<string>("materiaal"));
    var uniqueMaterials = materials.Distinct().OrderBy(z => z);
    

    etc.. maybe you even need to make sure materials all have the same casing: x => x.GetPropertyValue<string>("materiaal").ToLowerInvariant()

  • Patrick 33 posts 82 karma points
    Jul 14, 2015 @ 07:36
    Patrick
    0

    Sorry should've been a little more specific. My code is now as follows:

    string where = "Visible";
    var products = Umbraco.TypedContent(nodeId).DescendantsOrSelf("Product").Where(where);
    var materials = products.Select(x => x.GetPropertyValue<string>("materiaal").ToLowerInvariant());
    var uniqueMaterials = materials.Distinct().OrderBy(z => z);
    

    However it breaks after declaring materials. The result view in my (VS) watch responds as a results view: 'Children could not be evaluated'. If I would change x => x.GetPropertyValue<string>("materiaal").ToLowerInvariant() into: x => x.Name I do get a result. However not the result I would like to see ;)

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Jul 14, 2015 @ 07:47
    Sebastiaan Janssen
    0

    That exact code works on my machine. Are you sure that the document type Product has a property with the alias materiaal on it? And than there's nodes under your nodeId of document type Product?

    I see now that you're only selecting the materials, might be best not to do the .ToLowerInvariant() to preserve the original casing.

  • Patrick 33 posts 82 karma points
    Jul 14, 2015 @ 08:03
    Patrick
    0

    Yep,

    The strange thins is, when I use, almost, the same code in my razor file, like:

    var uniqueMateriaal = Model.Children.Where(where).DescendantsOrSelf("Product").Select(x => x.GetPropertyValue("materiaal")).Distinct().OrderBy(z => z);
    

    It does return the result as needed. Only difference is I use Model.Children as my starting point, however I can't seem to get it to work with the same syntax.

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Jul 14, 2015 @ 08:11
    Sebastiaan Janssen
    0

    That works too if I change "Visible" to x => x.IsVisible() :

    var products = Umbraco.TypedContent(74461).Children.Where(x => x.IsVisible());
    

    Okay well next up.. can you guess? Ah good-old-fashioned for-each:

    var materials = new List<string>();
    foreach (var product in products)
    {
        materials.Add(product.GetPropertyValue<string>("downloadLink"));
    }
    

    What do you get for materials.Count(); if you do this?

  • Patrick 33 posts 82 karma points
    Jul 14, 2015 @ 11:55
    Patrick
    0

    There is nothing wrong with some old-fashioned checking. Result is, your code works, which is the most important. Allthough the question which remains is why:

    Umbraco.TypedContent(nodeId).Children.Where(where).Select(x => x.GetPropertyValue("materiaal")).Distinct().OrderBy(z => z);
    

    works, and why the following doesn not:

    Umbraco.TypedContent(nodeId).Children.Where(where).DescendantsOrSelf("Product").Select(x => x.GetPropertyValue("materiaal")).Distinct().OrderBy(z => z);
    

    Which seems to be caused by the addition of DescendantsOrSelf

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Jul 14, 2015 @ 12:00
    Sebastiaan Janssen
    100

    Probably because you're asking for .Children first and then for the descendants of those children, so there's probably no descendants with document type "Product" (because the children ARE the products). So if you remove the .Children in the second query it should work, also note that you need to move the Where too:

    Umbraco.TypedContent(nodeId).DescendantsOrSelf("Product").Where(where).Select(x => x.GetPropertyValue("materiaal")).Distinct().OrderBy(z => z);
    
  • Patrick 33 posts 82 karma points
    Jul 14, 2015 @ 12:23
    Patrick
    0

    Sebastiaan thanks for your help and hints!

Please Sign in or register to post replies

Write your reply to:

Draft