Copied to clipboard

Flag this post as spam?

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


  • Filur 20 posts 154 karma points
    May 21, 2017 @ 11:07
    Filur
    1

    Converting IPublishedContent to strongly typed viewmodels w/o ModelsBuilder

    I have a custom view model that I use in my views. Here is the base class:

    public abstract class PageViewModel : RenderModel
    {
        public PageViewModel(IPublishedContent content) : base(content) { }
    
        public string Title => Content.GetVortoValue<string>("title");
        public string MenuName => Content.GetVortoValue<string>("menuName");
        public bool ShowInMenu => Content.GetPropertyValue<bool>("showInMenu");
    }
    

    So far so good. Now I want to fetch those pages in my backend:

    var publishedContent = UmbracoContext.Current.ContentCache.GetAtRoot();
    

    Now I have a collection of IPublishedContent. Is there any way to make Umbraco return the data typed as my different PageViewModel instances instead? Can you associate the published content with its corresponding view model type somehow? If so, I could construct them manually.

    As you can see, I'm not using ModelsBuilder, which is because I want to use GetVortoValue values instead of the regular GetPropertyValue.

    Currently I'm using my own factory class. Is there any way to make Umbraco use my custom factory?

  • Dave Woestenborghs 3345 posts 11308 karma points MVP 6x admin c-trib
    May 22, 2017 @ 09:47
    Dave Woestenborghs
    0

    Hi Filur,

    You can use GetVortoValue with models builder.

    What you need to do is create a new class file in the same folder where your models are generated. And than add your own implementation of the property. That way models builder will not generate it.

    public partial class MyContentType
    { 
      [ImplementPropertyType("myDifferentAlias")]
      public string MyProperty { get { return this.GetVortoValue<string>("myDifferentAlias"); } }
    }
    

    Also see the docs : https://github.com/zpqrtbnk/Zbu.ModelsBuilder/wiki/ModelsGenerationConfiguration#implement-property-type

    Dave

  • Filur 20 posts 154 karma points
    May 22, 2017 @ 11:41
    Filur
    0

    Hey Dave,

    Thanks for the tip, though I don't think it will help me very much in my case. The reason is that I will rely more or less exclusively on Vorto properties, so I would have to manually override the properties like in your example. So as far as I can tell I might as well rely on my current classes. Please correct me if I'm wrong here.

    Is there any way to make Umbraco use a custom factory, so I can have control over the creation of classes (similar to what ModelsBuilder does)?

  • Dave Woestenborghs 3345 posts 11308 karma points MVP 6x admin c-trib
    May 22, 2017 @ 11:48
    Dave Woestenborghs
    100

    Hi Filur,

    Should be possible, but never tried it.

    Have a look at this : https://github.com/zpqrtbnk/Zbu.ModelsBuilder/wiki/IPublishedContentModelFactory

    Would love to hear if you can get it to work.

    Dave

  • Filur 20 posts 154 karma points
    May 22, 2017 @ 17:20
    Filur
    0

    Hi again,

    This is what I'm looking for, thanks! I will give it a shot and update you if I manage to get it working as I want to :)

  • Filur 20 posts 154 karma points
    May 24, 2017 @ 16:36
    Filur
    0

    Hi agian Dave. Here is my current implementation which seems to work fine:

    My factory:

    public class ContentModelFactory : IPublishedContentModelFactory
    {
        private readonly Dictionary<string, Type> _registeredContentModelTypes = new Dictionary<string, Type>();
    
        public ContentModelFactory()
        {
            _registeredContentModelTypes = GetContentModelTypes().ToDictionary(t => CreateDocumentTypeAliasFromTypeName(t.Name), t => t);
        }
    
        public IPublishedContent CreateModel(IPublishedContent content)
        {
            Type type = null;
            if (_registeredContentModelTypes.TryGetValue(content.DocumentTypeAlias, out type))
            {
                return (IPublishedContent) Activator.CreateInstance(type, content);
            }
            return content;
        }
    
        private static IEnumerable<Type> GetContentModelTypes()
        {
            return Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(LGTContentModel)));
        }
    
        private static string CreateDocumentTypeAliasFromTypeName(string typeName)
        {
            var firstCharLowerCased = char.ToLowerInvariant(typeName[0]) + typeName.Substring(1);
    
            return firstCharLowerCased.Replace("ContentModel", string.Empty);
        }
    }
    

    Registration:

        PublishedContentModelFactoryResolver.Current.SetFactory(new ContentModelFactory());
    
Please Sign in or register to post replies

Write your reply to:

Draft