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.