Copied to clipboard

Flag this post as spam?

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


  • Alberto Fernandez 9 posts 79 karma points
    Sep 15, 2017 @ 14:21
    Alberto Fernandez
    0

    I am trying to create an IMedia object manually but it only set umbracoFile property. When I try to set umbracoWidth and save the object, the value is empty.

    const string mediaType = Constants.Conventions.MediaTypes.Image;
    var f = ApplicationContext.Current.Services.MediaService.CreateMedia(
                        Path.GetFileName(image.Uri.AbsoluteUri), -1, mediaType);
    
    f.SetValue("umbracoFile", image.Uri.AbsoluteUri);
    f.SetValue("umbracoWidth", image.Width);
    ApplicationContext.Current.Services.MediaService.Save(f);
    

    Anyone know why is this happening?

    Thank you in advance.

  • Marc Goodson 2141 posts 14344 karma points MVP 8x c-trib
    Sep 16, 2017 @ 08:43
    Marc Goodson
    0

    Hi Alberto

    It's not as intuitive as you might think programmatically manipulating the file associated with a media object, using the mediaservice.

    When you upload a file to the Umbraco Media section, as well as creating the Media item in the tree, Umbraco also uses it's configured FileSystemProviderManager to take responsibility for where the file is actually stored, and during this process the width, height and size in bytes of the image are discovered, and all get saved along with the reference to the file in the Media Item in the tree. If you are using the Image Cropper the umbracoFile property will contain a JSON blob containing details of all the crops as well as the file path. What I'm trying to explain is, it's not as simple as setting umbracoFile to be a path to an image.

    The way SetValue works on a Media object (well all content items too) is it looks at the type of the value being sent to it, and triggers different overloads to occur, appropriate to the type of value.

       // .NET magic to call one of the 'SetPropertyValue' handlers with matching signature 
            ((dynamic)this).SetPropertyValue(propertyTypeAlias, (dynamic)value);
    

    To trigger the uploading of an image programmatically via the FileSystemProviderManager (as if someone had uploaded the file via the backoffice), the value type for SetValue needs to be of type HttpPostedFile (or a class inheriting from HttpPostedFileBase)

    https://github.com/umbraco/Umbraco-CMS/blob/ac391f3bcdc084b1288b359cec7b246788a591eb/src/Umbraco.Core/Models/ContentBase.cs

    which then triggers the call the appropriate SetValue from the ContentExtensions for HttpPostedFile:

    https://github.com/umbraco/Umbraco-CMS/blob/9badb35c054ecc91630b69b1b6753c78427cb4a6/src/Umbraco.Core/Models/ContentExtensions.cs

    and you can see this is where the FileSystemProviderManager gets called to upload the file and set its properties.

    So in your above example, you are creating the 'Media' item in Umbraco but not uploading and associating the file correctly.

    If in your situation you are not 'uploading' the file by some kind of post, and therefore you don't have access to the HttpPostedFile to just pass it into SetValue, eg your files are already on disk on the server or something then you can fake the upload situation by creating a class that inherits from HttpPostedFileBase, programmatically constructing the FileStream.

    For example in this project to rotate umbarco images on github we have a 'MemoryStreamPostedFile' class that inherits HttpPostedFileBase:

    https://github.com/marcemarc/uSpinMeRightRound/blob/master/Solution/tooorangey.uSpinMeRightRound/Models/MemoryStreamPostedFile.cs

    and it's used with the SetValue to create the new version of the image, rotated in memory.

     var memoryStreamPostedFile = new MemoryStreamPostedFile(ms, newFileName);
                    var newMediaItem = mediaService.CreateMediaWithIdentity(mediaItem.Name + "_rotated" + (turns * 90).ToString(), mediaItem.ParentId, mediaItemAlias);
                    newMediaItem.SetValue("umbracoFile", memoryStreamPostedFile);
    

    Anyway hopefully this gives you the insight into what is going on...

    regards

    Marc

Please Sign in or register to post replies

Write your reply to:

Draft