Creating a Custom Widget in Sitefinity ASP.NET Core renderer
This guide demonstrates how to build a custom widget in Sitefinity .NET Core using a Card widget example. You’ll learn about the…
Creating a Custom Widget in Sitefinity ASP.NET Core renderer
This guide demonstrates how to build a custom widget in Sitefinity .NET Core using a Card widget example. You’ll learn about the recommended architecture, implementation patterns, and how to support multiple widget views.
Required Components vs Optional Components
Required Components ⭐
- ViewComponents folder with your ViewComponent class
- Views folder with at least one view template
- Service registration in Program.cs
Recommended but Optional Components
- Models folder for business logic
- ViewModels folder for view-specific models
- Entities folder for widget configuration
File Structure
YourProject/
├── ViewComponents/ (⭐ Required)
│ └── CardViewComponent.cs
├── Models/
│ ├── Card/
│ │ ├── ICardModel.cs
│ │ └── CardModel.cs
├── ViewModels/
│ └── Card/
│ └── CardViewModel.cs
├── Entities/
│ └── Card/
│ └── CardEntity.cs
└── Views/ (⭐ Required)
└── Shared/
└── Components/
└── Card/
├── Default.cshtml #Your widget's default outfit
└── Alternate.cshtml
Step 1: Create the Entity
public class CardComparisonEntity
{
private const string ViewSection = "View section";
[ContentSection(ViewSection)]
[ViewSelector]
public string ViewName { get; set; }
}
Naming Convention: Must have “Entity” suffix Purpose: Defines widget properties for the Sitefinity backend
In ASP.NET Core widgets, public properties of the entity are persisted and exposed in the designer interface for editing pages. This separation ensures that business logic is decoupled from rendering.
Step 2: Define the ViewModel
public class CardViewModel
{
public string ViewName { get; set; }
// Add other properties needed for the view
}
Naming Convention: Must have “ViewModel” suffix Purpose: Data container for views
Step 3: Implement the Model Interface
public interface ICardModel
{
Task<CardViewModel> InitializeViewModel(CardEntity entity);
}
Step 4: Implement the Model
public class CardModel : ICardModel
{
private readonly IODataRestClient restClient;
public CardModel(IODataRestClient service)
{
this.restClient = service;
}
public Task<CardViewModel> InitializeViewModel(CardEntity entity)
{
if (entity == null)
throw new ArgumentNullException(nameof(entity));
try
{
var viewModel = new CardViewModel
{
ViewName = entity.ViewName,
};
return Task.FromResult(viewModel);
}
catch (Exception ex)
{
throw new Exception("Failed to initialize CardViewModel", ex);
}
}
}
Naming Convention: Must have “Model” suffix Purpose: Contains business logic
Step 5: Create the ViewComponent (⭐ Required)
[SitefinityWidget(Title = "Card")]
public class CardViewComponent : ViewComponent
{
private readonly ICardModel model;
public CardViewComponent(ICardModel model)
{
this.model = model ?? throw new ArgumentNullException(nameof(model));
}
public virtual async Task<IViewComponentResult> InvokeAsync(IViewComponentContext<CardEntity> context)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
var viewModel = await this.model.InitializeViewModel(context.Entity);
return this.View(context.Entity.ViewName, viewModel);
}
}
*Key Points:
- Use the [SitefinityWidget] attribute to load the widget automatically in the Sitefinity Insert Widget dialogs.
- Inherit from ViewComponent for the Renderer to detect and render your functionality.
- The InvokeAsync method is required and is called automatically during page rendering.
- Use IViewComponentContext<T> to access the widget’s entity and properties during rendering.*
Step 6: Create the Views (⭐ Required)
Create view files in the Views/Shared/Components/Card folder:
// Default.cshtml
@model Renderer.ViewModels.Card.CardViewModel
<h3>Card</h3>
<!-- Add your default view content here -->
// Alternate.cshtml
@model Renderer.ViewModels.Card.CardViewModel
<div class="alternate-view">
<h3>Card - Alternate View</h3>
<!-- Add your alternate view content here -->
</div>
*Naming Conventions:
- The folder must match the widget name
- The default view should be named Default.cshtml*
Step 7: Register the Service (⭐ Required)
Add to Program.cs or Startup.cs:
builder.Services.AddScoped<ICardModel, CardModel>();
Best Practices and Tips
Widget Flow:
Request → ViewComponent → Model → ViewModel → View → Response
Support Multiple Views:
- Use the [ViewSelector] attribute in the entity
- Create multiple .cshtml files in the Views folder
- Pass ViewName from the entity to the View method
Common Pitfalls:
- Incorrect folder structure
- Missing required attributes
- Incorrect naming conventions
- Forgetting to register dependencies
Learn More
By following these steps and best practices, focusing on the required components (marked with ⭐), you can create robust and maintainable widgets in Sitefinity .NET Core. Happy coding!
Photo by Christin Hume on Unsplash
메타데이터
- post_id
- 9040dcb152c6
- slug
- creating-a-custom-widget-in-sitefinity-asp-net-core-renderer-9040dcb152c6
- url
- https://medium.com/@emilium/creating-a-custom-widget-in-sitefinity-asp-net-core-renderer-9040dcb152c6
- canonical_url
- https://medium.com/@emilium/creating-a-custom-widget-in-sitefinity-asp-net-core-renderer-9040dcb152c6
- author_url
- https://medium.com/@emilium
- status
- ok
- fetched_at
- 2026-06-24 11:06:28