Copied to clipboard

Flag this post as spam?

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


  • Kenneth Johnsen 9 posts 89 karma points
    Feb 04, 2016 @ 13:11
    Kenneth Johnsen
    0

    Setting tags on images via IContentBase

    I am trying to programmatically upload files to the media-section of umbraco backend, and set tags on them.

    I have added a property which is of the type "Tags" with property type alias "tags" to the mediatype "Image", and tested that I can manually add tags by typing in the field. This works fine.

    Now, I want to set tags programmatically using the following code:

                    var buffer = await file.ReadAsByteArrayAsync();
                    var stream = new MemoryStream(buffer);
                    var mediaService = Services.MediaService;
                    var image = mediaService.CreateMedia(filename, parentId, "Image");
                    image.SetValue("umbracoFile", filename, stream);
                    mediaService.Save(image);
    
                    // Tags
                    List<string> separators = new List<string>() { "¤¤" };
                    var tags = tagString.Split(separators.ToArray(), StringSplitOptions.RemoveEmptyEntries).Take(3);
                    image.SetTags("tags", tags, true);
    
                    id = image.Id;
    

    What happens is that the tables cmsTags and cmsTagRelationship gets populated, but no tags show up when I look at the properties of the image.

    It also seems like it breaks the editor. I can no longer type new tags in the field and have them turn the blue color. They just stay black, and if I type something else, it replaces what I typed before.

    I have tried various combinations of calling .Save before and after setting tags on the images, and also getting the image to a new variable after the save, setting tags, and saving again.

    I have checked the tables cmsTags, cmsTagRelationShip, cmsPropertyType, cmsDataType and cmsContentType, and the tags I create programmatically looks just like the ones create manually.

    It would seem that I am missing something.

    • Should the tags be created before setting them on the images (and how?).
    • Is there some step that I'm missing when saving?

    BR. Kenneth.

  • Kenneth Johnsen 9 posts 89 karma points
    Feb 04, 2016 @ 13:34
    Kenneth Johnsen
    0

    Ps. Just tried adding a row to cmsTags, and one to cmsTagRelationship. This behaves just like the ones created programmatically (i.e. not showing up in the property on the image).

  • Tom Steer 155 posts 548 karma points
    Feb 04, 2016 @ 13:55
    Tom Steer
    0

    Hi Kenneth,

    Not sure if you just haven't pasted the code but are you saving the IContent after calling SetTags?

    Thanks,

    Tom

  • Kenneth Johnsen 9 posts 89 karma points
    Feb 04, 2016 @ 14:04
    Kenneth Johnsen
    0

    Hi Tom,

    Yes, I have tried various combinations of:

    Create image, save, set tags

    Create image, set tags, save

    Create image, save, get image to new variable, set tags, save.

    This is the code as it is presently (not working):

    var buffer = await file.ReadAsByteArrayAsync();
                    var stream = new MemoryStream(buffer);
                    var mediaService = Services.MediaService;
                    var image = mediaService.CreateMedia(filename, parentId, "Image");
                    image.SetValue("umbracoFile", filename, stream);
                    mediaService.Save(image);
    
                    // Tags
                    var imageForTags = mediaService.GetById(image.Id);
                    List<string> separators = new List<string>() { "¤¤" };
                    var tags = tagString.Split(separators.ToArray(), StringSplitOptions.RemoveEmptyEntries).Take(3);
                    imageForTags.SetTags("tags", tags, true);
                    mediaService.Save(imageForTags);
    
                    id = image.Id;
    

    BR. Kenneth.

  • Tom Steer 155 posts 548 karma points
    Feb 04, 2016 @ 14:11
    Tom Steer
    0

    Do you get any errors in the browser console when viewing the page in Umbraco?

    Thanks,

    Tom

  • Kenneth Johnsen 9 posts 89 karma points
    Feb 04, 2016 @ 14:18
    Kenneth Johnsen
    0

    Aha! Yes. I get the following:

    Console error

    BR. Kenneth.

  • Kenneth Johnsen 9 posts 89 karma points
    Feb 04, 2016 @ 14:20
    Kenneth Johnsen
    0

    The things I am trying to tag on are things like product number, brand, type etc., given as parts of the filename.

    I loop through a lot of images, so some of them are bound to have the same brand, f.ex.

    I'm not sure if the same term exists more than once in the filename, but maybe I should do a distinct on my "tags" variable?

  • Tom Steer 155 posts 548 karma points
    Feb 04, 2016 @ 14:25
    Tom Steer
    0

    Hi Kenneth,

    Maybe trying calling .Distinct() on the tags array when passing it to SetTags. That error message makes it sound as if there are duplicate tags.

    Thanks,

    Tom

  • Kenneth Johnsen 9 posts 89 karma points
    Feb 04, 2016 @ 14:26
    Kenneth Johnsen
    0

    Thanks, I will try that. Seems likely.

    BR. Kenneth.

  • Kenneth Johnsen 9 posts 89 karma points
    Feb 05, 2016 @ 08:24
    Kenneth Johnsen
    0

    Calling Distinct() made no difference.

    I then tried a simple experiment, just retrieving an existing image, setting tags, and saving. That doesn't seem to work either.

    I still get the "Error: Duplicates in a repeater are not allowed. Repeater: tag in model.value" in the console when viewing the image in the backoffice.

    The code has now been boiled down to:

            var service = Services.MediaService;
            var item = service.GetById(2120);
            var tags = new List<string>() { "Test1", "Test2", "Test3" };
            item.SetTags("tags", tags, true);
            service.Save(item);
    

    I still get the rows in cmsTags and cmsTagRelationship, and everything seems to look OK in the DB.

    I'm thinking the next step is to compare the entire DB to see how it looks when 1) Tags are entered manually. 2) Tag are created with SetTags.

    There must be something that SetTags doesn't do, which is needed for the tags to show correctly.

    BR. Kenneth.

    BR. Kenneth.

  • Kenneth Johnsen 9 posts 89 karma points
    Feb 05, 2016 @ 10:19
    Kenneth Johnsen
    0

    OK, so I did the following:

    1) Start with no tags on any image.

    2) Add a tag to an image.

    3) Make a DB backup.

    4) Add a second tag to the image.

    5) Write down which tables had new/updated data

    6) Make a DB backup.

    7) Add a third tag programmatically using .SetTags().

    8) Compare DB after third tag was added.

    So, all the same tables were touched, which were the following:

    • Contentversion - update versiondate field

    • Contentxml - update xml field

    • Cmspropertydata - update datanvarchar field

    • Cmstag - insert 1 row

    • Cmstagrelationship - insert 1 row

    • Cmscacheinstruction - insert 1 row

    • Umbracolog - insert 1 row

    • Umbraconode - update 2 rows

    • Umbracoserver - update 2 rows

    However, the one called cmsPropertyData looks different after adding the third tag using SetTags.

    DB after adding third tag with SetTags

    Looks like the data is no longer represented as a JSON array, but just a comma-separated list of the tags. Could this be a bug?

    I noticed in the Tags data type, that I can choose between "JSON" and "CSV in "Storage Type".

    Mine is set to "JSON".

    Could it be that SetTags does not take this into account, and just always store it as CSV, whereas manually entering tags will honor "Storage Type"?

    BR. Kenneth.

  • Tom Steer 155 posts 548 karma points
    Feb 05, 2016 @ 10:34
    Tom Steer
    100

    Hi Kenneth,

    Looking at the Umbraco source it looks like by default it sets the storage type to CSV when calling SetTags()

    https://github.com/umbraco/Umbraco-CMS/blob/bfbc6595fb165063fde40f653fbc27feb112a858/src/Umbraco.Core/Models/ContentExtensions.cs#L691

    However there does seem to be an overload for this extension method which allows you to specify the storage type:

    https://github.com/umbraco/Umbraco-CMS/blob/bfbc6595fb165063fde40f653fbc27feb112a858/src/Umbraco.Core/Models/ContentExtensions.cs#L706

    Hope this helps.

    Thanks,

    Tom

  • Kenneth Johnsen 9 posts 89 karma points
    Feb 05, 2016 @ 10:53
    Kenneth Johnsen
    0

    Yup. That did the trick :-)

    Kinda weird, though, that SetTags doesn't look up the storage type set on the data type, and just use that as default.

    But I can live with using the overload. Maybe even look up the selected storage type on the datatype, and pass that back in the overload (if somebody changes the storag type in the future).

    Thanks a lot for all your help!

    BR. Kenneth.

  • Tom Steer 155 posts 548 karma points
    Feb 05, 2016 @ 10:55
    Tom Steer
    0

    No worries, glad you have it all working now :)

  • John Bergman 370 posts 907 karma points
    7 days ago
    John Bergman
    0

    I know this is a little old, but I was looking at the code, shouldn't the storage group "default" use what is set in the control, instead of default? Am I missing something?

Please Sign in or register to post replies

Write your reply to:

Draft