Force Image Cache Refresh Programmatically

The best solution I found, to force the browser cache to refresh for an image, is to modify the image url in the html.

Example:
I have an image with this url: “/images/mario-profile-photo.jpeg”.
Change the url to: “/images/mario-profile-photo.jpeg?updated={DateTime.Now.Ticks}“.

So, I lied, sorry! This will make the browser request the image again, because the url is different. It doesn’t really refresh the cache.

Using DateTime.Now.Ticks will force the refresh every time the page loads, so I don’t recommend using it.

If you have the time of when the photo was last updated, use that instead! Something like: {Photo.UpdateDate.Ticks}
This way, you will only request a new image when it is different from the one you already have in cache.

Note: the “?updated=” property is just a name, you can use whatever you want. The important thing is to modify the url.

For Umbraco developers: When saving an image, do not forget to set it’s UpdateDate! Umbraco doesn’t update that property automatically.

Hope this helps,
Thanks for reading!
Mário

Syncing Member Types with uSync

This took me longer to figure out than it should have.

uSync has MemberType synchronization disabled by default.

To enable it simply go to Config\uSyncBackOffice.Config and set MemberTypeHandler to true.

<Handlers Group="default" EnableMissing="true">
    <HandlerConfig Name="uSync: DataTypeHandler" Enabled="true" />
    <HandlerConfig Name="uSync: TemplateHandler" Enabled="true" />

    <HandlerConfig Name="uSync: ContentTypeHandler" Enabled="true" />
    <HandlerConfig Name="uSync: MediaTypeHandler" Enabled="true" />
    <HandlerConfig Name="uSync: LanguageHandler" Enabled="true" />
    <HandlerConfig Name="uSync: DictionaryHandler" Enabled="true" />
    <HandlerConfig Name="uSync: MacroHandler" Enabled="true" />
    <HandlerConfig Name="uSync: DataTypeMappingHandler" Enabled="true" />
    <HandlerConfig Name="uSync: MemberTypeHandler" Enabled="true" />
    
    <!-- content edition - if installed -->
    <HandlerConfig Name="uSync: ContentHandler" Enabled="true" />
    <HandlerConfig Name="uSync: MediaHandler" Enabled="true" />
</Handlers>

Thanks for reading!

Mário Nunes

Working with Umbraco 7.6 New Pickers

With the old pickers, we could do something like this:

page.SetValue("myPicker", content.Id);

With the new pickers, we can’t use IDs anymore, we have to use UDIs instead. They look like this:

"umb://document/28b551d1e9e74c758686604c9168b910"

So how can we get the content UDI?
If we have an IContent, we can simply use the extension

string udi = content.GetUdi().ToString();

If we have an IPublishedContent, we need to do a little bit more work.
Umbraco provides a built in function to create UDIs. To use it, we need these:

using Umbraco.Core;
using static Umbraco.Core.Constants;

Get the UDI like this:

string udi = Udi.Create(UdiEntityType.Document, content.GetKey()).ToString();

If you want to set multiple items, separate the udis with a comma. The resulting string should be like this:
"umb://document/28b551d1e9e74c758686604c9168b910,umb://document/28b551d1e9e74c758686604c9168b912,..."


To clean up the code, I created an extension class.

    using Umbraco.Core;
    using Umbraco.Core.Models;
    using Umbraco.Web;
    using static Umbraco.Core.Constants;

    public static class UmbracoExtensions
    {
        /// <summary>
        /// Gets the specified content udi.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <returns>The content udi.</returns>
        public static string GetUdi(this IPublishedContent content)
        {
            return Udi.Create(UdiEntityType.Document, content.GetKey()).ToString();
        }
    }

With this extension, you can set the pickers with IPublishedContent with just one line of code!

page.SetValue("myPicker", content.GetUdi());


So why not use IContent all the time?
To get an IContent, we need to use a service like MediaService or ContentService, they are much slower that getting and IPublishedContent through Umbraco.TypedContent(), which gets it from cache.

UPDATE: Support for member pickers. Other pickers might need additional code too.

public static string GetUdi(this IPublishedContent content)
{
    string entityType = UdiEntityType.Document;

    if (string.Equals(Models.Member.ModelTypeAlias, content.ContentType.Alias))
    {
        entityType = UdiEntityType.Member;
    }

    return Udi.Create(entityType, content.GetKey()).ToString();
}

Thanks for reading,
Mário Nunes