Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more

Get content type from content id without loding content.

Vote:
 

Hi,

Is there a nice way to get the type of a content with contentreference or id without loading the content?

I found this project https://github.com/vimvq1987/CatalogContentTypeResolver but it uses methods from Commerce and we use CMS only.

I´m rebuilding the Link validation scheduled job to be able to detect if the ~/link/{guid}.aspx is a reference to a block.

We have hundreds of references in the softlink table to block content that all get market as 404 in the scheduled job.

Any idées?

#203115
Apr 09, 2019 15:33
Vote:
 

Hi,

The key part is of your question is "nice way"and there isn't anything out-of-the-box that does what you want. Using the ContentLoader is generally preferred and performant, also by default IContent is cached for 12 hours with sliding expiration.

Have you experienced a database bottleneck when running your scheduled job?

As a code experiment I knocked up the following:

[ServiceConfiguration]
public class ContentTypeResolver
{
    private static readonly ILogger Logger = LogManager.GetLogger(typeof(ContentTypeResolver));
    private readonly IDatabaseExecutor _executor;

    private const string Query =
        "SELECT contentType.ModelType FROM tblContent content LEFT JOIN tblContentType contentType ON content.fkContentTypeID = contentType.pkID WHERE content.pkID = {0}";

    public ContentTypeResolver(IDatabaseExecutor executor)
    {
        _executor = executor;
    }

    public Type GetType(ContentReference contentLink)
    {
        if (contentLink == null)
        {
            throw new ArgumentNullException(nameof(contentLink));
        }

        var query = string.Format(Query, contentLink.ID);

        string typeName = null;

        _executor.Execute(delegate
        {
            try
            {
                var command = _executor.CreateCommand();
                command.CommandText = query;
                command.CommandType = CommandType.Text;

                using (var reader = command.ExecuteReader(CommandBehavior.SingleResult))
                {
                    if (reader.Read())
                    {
                        typeName = reader.GetString(0);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"Could not get ModelType from content reference {contentLink.ID}.", ex);
            }
        });

        if (string.IsNullOrEmpty(typeName))
        {
            return null;
        }

        try
        {
            return Type.GetType(typeName);
        }
        catch (Exception ex)
        {
            Logger.Error($"Could not get a type from {typeName}.", ex);
            return null;
        }
    }
}

Like I said, I wouldn't personally recommend this approach, but I think you could fairly quickly build it out into something like the example you provided.

/Jake

#203121
Edited, Apr 09, 2019 18:40
Vote:
 

Just to add an important caveat to the first part of Jake's answer - By default content from the ContentLoader is cached for 12 hours however, as of 11.1, for performance reasons, content which is loaded in the context of a scheduled job is actually only cached for 1 minute by default (though you can override that if necessary). You can read (slightly) more here:
https://world.episerver.com/documentation/developer-guides/CMS/scheduled-jobs/

#203122
Apr 09, 2019 19:41
Vote:
 

Thx Jack!

Both for the code and for the confirmation that no api is available.

Regards
/Jesper

#203226
Apr 12, 2019 8:57
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.