1
votes

I am currently writing an api for a custom application my company is writing. Part of this involves getting published content out in JSON format. When I try serializing ipublishedcontent directly it obviously attempts to serialize all of the umbraco data and relations that I simply don't need (in fact it fails with a stack overflow). Is there a way to get just the custom properties from an item of content without specifying the fields?

I am using webapi and passing it objects to serialize itself and I'm using a dynamic to manually specify the fields. The Product type which I'm initially selecting into is from modelsbuilder. My code currently looks a little like this:

public object Get(string keywords = "")
{
    // Get Data from Umbraco
    var allProducts = Umbraco.TypedContent(1100).Children.Select(x => new Product(x));
    if (keywords != "")
    {
        allProducts = allProducts.Where(x => x.Name.Contains(keywords));
    }


    return allProducts.Select(x => new
    {
        id = x.Id,
        name = x.Name,
        price = x.Price
    });
}

It seems to me that there should be a simple way to do this without having to create a dynamic with just the fields I want but I can't work it out. I just don't want to have to change my code every time the document type in umbraco changes!

2

2 Answers

0
votes

You can use Ditto to map your data into an object.

Create an object with properties that match the alias's of your fields (case insensitive)

 public class Product{ 
    public int id {get;set;} 
    public string name {get;set;} 
    public string price {get;set;} 
 }

Then map a single or collection of IPublishedContent objects using .As

return allProducts.As<Product>();

You can use the UmbracoProperty attribute to specify the alias too if it is different than you need for your json or use the JsonProperty attribute to change the name on serialize.

0
votes

Take a look at the code in the MemberListView - it does a similar thing while retrieving Members without knowing in advance what the properties on the MemberType will be:

https://github.com/robertjf/umbMemberListView/blob/master/MemberListView/Models/MemberListItem.cs

For example:

[DataContract(Name = "content", Namespace = "")]
public class MemberListItem
{
    // The following properties are "known" - common to all IPublishedContent
    [DataMember(Name = "id")]
    public int Id { get; set; }

    [DataMember(Name = "name")]
    public string Name { get; set; }

    [DataMember(Name = "contentType")]
    public IContentType ContentType { get; set; }

    // This one contains a list of all other custom properties.
    private Dictionary<string, string> properties;
    [DataMember(Name = "properties")]
    public IDictionary<string, string> Properties
    {
        get
        {
            if (properties == null)
                properties = new Dictionary<string, string>();
            return properties;
        }
    }
}

MemberListView converts to this from a list of SearchResult using AutoMapper, but you could just as easily map it from IPublishedContent.