Copied to clipboard

Flag this post as spam?

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


  • Marco Lusini 176 posts 1370 karma points
    Apr 19, 2017 @ 10:21
    Marco Lusini
    0

    Getting umbracoFile property within a ModelBuilder model

    Hi,

    after a looong pause, I'm trying to get back at Umbraco in the "right way" (tm)...

    I have created a "File Media" Document Type with a Media Picker property called "Allegato" and I want to override the Url property of the model generated by ModelBuilder in order to return the file media Url (i.e. the "umbracoFile" property of the Media Picker).

    Up to now this is the best solution I have found:

     public partial class FileMedia
     {
        public override string Url
        {
            get
            {
                try
                {
                    int allegatoID = Int32.Parse(this.Allegato);
                    var mediaService = ApplicationContext.Current.Services.MediaService;
                    var allegatoMedia = mediaService.GetById(allegatoID);
                    return allegatoMedia.GetValue("umbracoFile").ToString();
                }
                catch (FormatException e)
                {
                    return base.Url;
                }
            }
        }
    }
    

    but it uses ApplicationContext.Current property, which should not be done as explained in Common Pitfalls.

    Is there a better way?

    Thanks, Marco

  • Alex Skrypnyk 6163 posts 24143 karma points MVP 8x admin c-trib
    Apr 19, 2017 @ 18:33
    Alex Skrypnyk
    2

    Hi Marco

    The best way to get URL of media is to use Umbraco Helper and TypedMedia:

    var media = Umbraco.TypedMedia(1234);
    var image = media.Url;
    

    In your case:

     public partial class FileMedia
     {
        public override string Url
        {
            get
            {
                    int allegatoID = Int32.Parse(this.Allegato);
                    var media = Umbraco.TypedMedia(allegatoID);
                    return media.Url;
            }
        }
    }
    

    Don't use services for rendering media items of course.

    Thanks,

    Alex

  • Marco Lusini 176 posts 1370 karma points
    Apr 20, 2017 @ 08:57
    Marco Lusini
    0

    Thanks Alex,

    I have seen UmbracoHelper class, but I don't think I have an Umbraco property ready to use, so the only way I found was to resort to the UmbracoContext singleton (which is one of the pitfall...). This is the code generated by ModelBuilder:

    //------------------------------------------------------------------------------
    // <auto-generated>
    //   This code was generated by a tool.
    //
    //    Umbraco.ModelsBuilder v3.0.7.99
    //
    //   Changes to this file will be lost if the code is regenerated.
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    using System;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    using System.Web;
    using Umbraco.Core.Models;
    using Umbraco.Core.Models.PublishedContent;
    using Umbraco.Web;
    using Umbraco.ModelsBuilder;
    using Umbraco.ModelsBuilder.Umbraco;
    
    namespace Umbraco.Web.PublishedContentModels
    {
        /// <summary>File Media</summary>
    [PublishedContentModel("fileMedia")]
    public partial class FileMedia : Base
    {
    #pragma warning disable 0109 // new is redundant
        public new const string ModelTypeAlias = "fileMedia";
        public new const PublishedItemType ModelItemType = PublishedItemType.Content;
    #pragma warning restore 0109
    
        public FileMedia(IPublishedContent content)
            : base(content)
        { }
    
    #pragma warning disable 0109 // new is redundant
        public new static PublishedContentType GetModelContentType()
        {
            return PublishedContentType.Get(ModelItemType, ModelTypeAlias);
        }
    #pragma warning restore 0109
    
        public static PublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<FileMedia, TValue>> selector)
        {
            return PublishedContentModelUtility.GetModelPropertyType(GetModelContentType(), selector);
        }
    
        ///<summary>
        /// Allegato
        ///</summary>
        [ImplementPropertyType("allegato")]
        public string Allegato
        {
            get { return this.GetPropertyValue<string>("allegato"); }
        }
      }
    }
    

    and this is my last override.cs:

    using System;
    
    namespace Umbraco.Web.PublishedContentModels
    {
        public partial class FileMedia
        {
            public override string Url
            {
                get
                {
                    int allegatoID;
                    if (Int32.TryParse(this.Allegato, out allegatoID))
                    {
                        var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
                        return umbracoHelper.TypedMedia(allegatoID).Url;
                    }
                    else
                    {
                        return "";
                    }
                }
            }
        }
    }
    
  • Alex Skrypnyk 6163 posts 24143 karma points MVP 8x admin c-trib
    Apr 20, 2017 @ 09:08
    Alex Skrypnyk
    0

    Hi Marco

    Yes, now we need to avoid instantiation of "UmbracoHelper".

    What about using extension methods instead overriding class?

    You can create .GetMediaUrlById extention method for example.

    Alex

  • Marco Lusini 176 posts 1370 karma points
    Apr 20, 2017 @ 09:15
    Marco Lusini
    0

    Uhm... I am not sure to understand. Where shoud I create the extension method? If I add it to the Model class it won't be able to see Umbraco, IIUIC.

    Yet I prefer to override the Url property (it is a cleaner approach to me), and reading again the common pitfall page, I think that using the singleton is not too bad.

  • Alex Skrypnyk 6163 posts 24143 karma points MVP 8x admin c-trib
    Apr 20, 2017 @ 12:24
  • Marco Lusini 176 posts 1370 karma points
    Apr 20, 2017 @ 13:33
    Marco Lusini
    0

    Ehm... this example uses a static copy of UmbracoHelper, which is a bigger "no no" wrt to the common pitfall Static references to web request instances :-D

  • Alex Skrypnyk 6163 posts 24143 karma points MVP 8x admin c-trib
    Apr 20, 2017 @ 17:08
    Alex Skrypnyk
    1

    Aha, you caught me, Marco, you are absolutely right!!!

    So we have to pass UmbracoHelper instance to our method.

  • Marco Lusini 176 posts 1370 karma points
    Apr 24, 2017 @ 13:10
    Marco Lusini
    100

    In the mean time I wrote a custom Url Provider which does the job way too well, to the point that the properties tab in content items shows some error related to the url colliding some other content... :-D

    I think I'll end up using extension methods anyway.

    Thanks for you time Alex.

  • Alex Skrypnyk 6163 posts 24143 karma points MVP 8x admin c-trib
    Apr 24, 2017 @ 13:27
    Alex Skrypnyk
    0

    You are welcome, Marco.

    Have a nice evening.

    Alex

Please Sign in or register to post replies

Write your reply to:

Draft