LinkResolver
Smartstore stores navigation targets as compact link expressions like product:123, topic:about-us|_blank or https://example.com. ILinkResolver translates these expressions to concrete URLs and labels, ensuring store and ACL security and reusing results from a memory cache.
Expression format
A link expression consists of schema:target|linkTarget?query:
schema
Identifier selecting a provider (product, category, topic, etc.). If omitted, the string is treated as a raw URL.
target
Entity id, system name or URL path.
linkTarget
Optional window target such as _blank.
query
Optional query string appended to the generated link.
Built‑in schemas are:
product
Product detail page
category
Category listing
manufacturer
Manufacturer page
topic
Topic by id or system name
url
Absolute or application-relative URL (~/path)
file
Static file path
Providers implement ILinkProvider and can add further schemas.
Resolving links
Inject ILinkResolver and call ResolveAsync with an expression:
public class LinkDemo
{
private readonly ILinkResolver _links;
public LinkDemo(ILinkResolver links) => _links = links;
public async Task<string> GetProductLinkAsync(int id)
{
var result = await _links.ResolveAsync($"product:{id}");
return result.Status == LinkStatus.Ok ? result.Link : string.Empty;
}
}ResolveAsync returns a LinkResolutionResult containing the final URL, a localized label and the entity identifiers when available. Access control is evaluated by store mapping and ACL before a link is considered valid.
Custom providers
Custom schemas are added by implementing ILinkProvider and registering it via DI:
public class BlogPostLinkProvider : ILinkProvider
{
public int Order => 100;
public IEnumerable<LinkBuilderMetadata> GetBuilderMetadata() =>
new[] { new LinkBuilderMetadata { Schema = "blogpost", Icon = "fa fa-blog", ResKey = "Common.Entity.BlogPost" } };
public Task<LinkTranslationResult> TranslateAsync(LinkExpression expr, int storeId, int languageId)
{
// look up blog post and return URL/label
}
}The metadata controls the link picker UI in the admin panel.
Cache invalidation
Resolved links are cached under a key that includes schema, store, language and roles. When the underlying entity changes, invalidate the cache with:
_linkResolver.InvalidateLink("product", productId);A built-in DefaultLinkInvalidator listens to update events for core entities and clears entries automatically.
Last updated
Was this helpful?