Overview
The following article describes the different parts that constitute an ASP.NET Core widget. It also specifies where you should place them and how should you name them.
ViewComponent (required)
Location
/ViewComponents/SitefinityDataViewComponent.cs
Naming convention
The name of the class must have the ViewComponent
suffix.
Description
The ViewComponent
class must comply with the following:
- The class must be public.
- The class must be marked with the
[SitefinityWidget]
attribute.
This way, the widget is loaded and displayed during the page editing, inside the Sitefinity CMS widget selector.
- The class must contain a public
InvokeAsync
method which receives as argument IViewComponentContext<SitefinityDataEntity>
.
For more information, see Microsoft documentation » View components in ASP.NET Core.
Following is an example of a ViewComponent
class:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
using System.Threading.Tasks; |
|
using Microsoft.AspNetCore.Mvc; |
|
using Progress.Sitefinity.AspNetCore.ViewComponents; |
|
using sitefinity_data.Models.SitefinityData; |
|
|
|
namespace sitefinity_data.ViewComponents |
|
{ |
|
// The view component for accessing Sitefinity data. |
|
[SitefinityWidget] |
|
public class SitefinityDataViewComponent : ViewComponent |
|
{ |
|
private ISitefinityDataModel model; |
|
|
|
// Initializes a new instance of the <see cref="SitefinityDataViewComponent"/> class. |
|
public SitefinityDataViewComponent(ISitefinityDataModel model) |
|
{ |
|
this.model = model; |
|
} |
|
|
|
// Invokes the view component. |
|
// <param name="context">The view component context.</param> |
|
// <returns>The view component result.</returns> |
|
public async Task<IViewComponentResult> InvokeAsync(IViewComponentContext<SitefinityDataEntity> context) |
|
{ |
|
var items = await this.model.GetViewModels(context.Entity); |
|
return this.View(items); |
|
} |
|
} |
|
} |
View (required)
Location
/Views/Shared/Components/SitefinityData/Default.cshtml
Naming convention
The naming of the folders where you place the Default.cshtml
is strict.
SitefinityData
folder is the name of your widget.
RECOMMENDATION: We recommend naming the view Default.cshtml
Description
In this folder, in addition to the Default.cshtml
, you can place all views available for a particular ViewComponent
.
Following is an example of a View
file:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
@model IList<sitefinity_data.ViewModels.SitefinityData.ItemViewModel> |
|
|
|
<h1>News items</h1> |
|
|
|
@foreach (var item in this.Model) |
|
{ |
|
<ul> |
|
<li> |
|
@item.Title |
|
@if (item.ThumbnailUrl != null) |
|
{ |
|
<img src="@item.ThumbnailUrl" /> |
|
} |
|
</li> |
|
</ul> |
|
} |
Entity (optional)
Location
/Models/SitefinityData/SitefinityDataEntity.cs
Naming convention
The name of the class must have the Entity
suffix.
Description
The Entity
class represents the data that is persisted in the database. This separates the logic for persisting the values of the properties, kept in the Entity
class, from the business logic for the view components, kept in the Model
class
The Entity
class presents only plain public properties with get or set. This is visualized in Sitefinity CMS backend, through the widget property editors. The widget editor autogenerates a separate field for each property of the entity.
You can use attributes and data annotations to configure the look of the fields or their visibility, to group them in sections and categories, to set their default values, to validate them, etc.
For more information, see Autogenerated widget property editors for ASP.NET Core.
Following is an example of an Entity
class:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
using System.ComponentModel; |
|
|
|
namespace sitefinity_data.Models.SitefinityData |
|
{ |
|
public class SitefinityDataEntity |
|
{ |
|
// Gets or sets a value indicating whether to hide the related image. |
|
[DisplayName("Hide related image")] |
|
public bool HideImage { get; set; } |
|
} |
|
} |
Model (optional)
Location
/Models/SitefinityData/SitefinityDataModel.cs
and
/Models/SitefinityData/ISitefinityDataModel.cs
Naming convention
The name of the class must have the Model
suffix.
Description
This classes contains the business logic of the widget. They receive the data from the entity and process it to generate a ViewModel
with the data needed by the View
.
RECOMMENDATION: Although none of these classes are required, we recommend you add all logic for the widget in them, including the requests to Sitefinity CMS services and to third-party providers.
Sitefinity CMS built-in widgets, expose an interface for the model and take advantage of the built-in ASP.NET Core dependency injection mechanism to provide capability for replacing and extending the default logic.
Following is an example of a Model
class:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Threading.Tasks; |
|
using Progress.Sitefinity.AspNetCore.SitefinityApi; |
|
using Progress.Sitefinity.Renderer.Entities.Content; |
|
using sitefinity_data.Dto; |
|
using sitefinity_data.ViewModels.SitefinityData; |
|
|
|
namespace sitefinity_data.Models.SitefinityData |
|
{ |
|
/// <summary> |
|
/// The model class. |
|
/// </summary> |
|
public class SitefinityDataModel : ISitefinityDataModel |
|
{ |
|
private readonly IRestClient service; |
|
/// <summary> |
|
/// Initializes a new instance of the <see cref="SitefinityDataViewComponent"/> class. |
|
/// </summary> |
|
/// <param name="service">The rest service.</param> |
|
public SitefinityDataModel(IRestClient service) |
|
{ |
|
this.service = service; |
|
} |
|
|
|
|
|
/// <summary> |
|
/// Gets the view models. |
|
/// </summary> |
|
/// <param name="entity">The entity object.</param> |
|
/// <returns>The generated view models.</returns> |
|
public async Task<IList<ItemViewModel>> GetViewModels(SitefinityDataEntity entity) |
|
{ |
|
// when using the OData client, the url is automatically prefixed with the value of web the service and the sitefinity instance url |
|
// we use an expand the get the related image |
|
|
|
var getAllArgs = new GetAllArgs |
|
{ |
|
// required parameter, specifies the items to work with |
|
Type = KnownContentTypes.News |
|
}; |
|
|
|
// optional parameter, specifies the fields to be returned, if not specified |
|
// the default service response fields will be returned |
|
getAllArgs.Fields.Add(nameof(Item.Title)); |
|
|
|
// specifies the related fields to be included in the response (like related data or parent relationships) |
|
if (!entity.HideImage) |
|
getAllArgs.Fields.Add(nameof(Item.Thumbnail)); |
|
|
|
var response = await this.service.GetItems<Item>(getAllArgs); |
|
var viewModels = response.Items.Select(x => this.GetItemViewModel(x)).ToList(); |
|
return viewModels; |
|
} |
|
|
|
private ItemViewModel GetItemViewModel(Item item) |
|
{ |
|
var viewModel = new ItemViewModel() |
|
{ |
|
Title = item.Title |
|
}; |
|
|
|
if (item.Thumbnail != null && item.Thumbnail.Length == 1) |
|
{ |
|
viewModel.ThumbnailUrl = item.Thumbnail[0].ThumbnailUrl; |
|
} |
|
|
|
return viewModel; |
|
} |
|
} |
|
} |
Following is an example of the model interface class:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
using System.Collections.Generic; |
|
using System.Threading.Tasks; |
|
using sitefinity_data.ViewModels.SitefinityData; |
|
|
|
namespace sitefinity_data.Models.SitefinityData |
|
{ |
|
/// <summary> |
|
/// The model interface. |
|
/// </summary> |
|
public interface ISitefinityDataModel |
|
{ |
|
/// <summary> |
|
/// Gets the view models. |
|
/// </summary> |
|
/// <param name="entity">The entity object.</param> |
|
/// <returns>The generated view models.</returns> |
|
Task<IList<ItemViewModel>> GetViewModels(SitefinityDataEntity entity); |
|
} |
|
} |
ViewModel (optional)
Location
/Models/WidgetName/WidgetViewModel.cs
Naming convention
The name of the class must have the ViewModel
suffix.
Description
This class is intended to contain Plain old CLR object (POCO) for providing data to the widget view. You can have more than one ViewModel
class for a single widget, depending on the specifics of your different views.
RECOMMENDATION: We recommend using a ViewModel
class to separate the logic of the view from the business logic.
Following is an example of a ViewModel
class:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
namespace sitefinity_data.ViewModels |
|
{ |
|
public class NewsViewModel |
|
{ |
|
// Gets or sets the title. |
|
public string Title { get; set; } |
|
|
|
// Gets or sets the thumbnail. |
|
public Image Thumbnail { get; set; } |
|
} |
|
|
|
// The image view model. |
|
public class Image |
|
{ |
|
// Gets or sets the thumbnail url. |
|
public string ThumbnailUrl { get; set; } |
|
} |
|
} |