---
title: Custom widget attributes
slug: configured-commerce/sdk/custom-widget-attributes
docTags: 
createdAt: 2026-08-05T19:24:05.151Z
---

After creating a custom widget, it is likely that you will also want to include custom attributes that the end user can access and alter as needed based on the widget.

## ContentFieldAttributes

ContentFieldAttributes can be used to customize the display/editing of a property on a widget. An example of this is adding a Country Selection ability to a widget.

First create a new class with the following content. In this example we are inheriting from an existing attribute. An important thing to note is that we override GenericType to return typeof(drop-downContentFieldAttribute). This is required to make use of the existing html template, without it a new html template would be required.

```c#
public class CountrySelector : drop-downContentFieldAttribute
{
    public override Type GenericType => typeof(drop-downContentFieldAttribute);
 
    public CountrySelector() : base(new string[0])
    {
        var countries = DependencyLocator.Current.GetInstance<IUnitOfWorkFactory>().GetUnitOfWork().GetRepository<Country>().GetTable().OrderBy(o => o.Name).ToList();
        this.Options = countries.Select(o => new KeyValuePair<string, string>(o.Id.ToString(), o.Name)).ToArray();
    }
}
```

If a custom html template is needed for our new attribute, then the Template property can be set in our new class. To make sure of a razor view from the extensions project, this value needs to start with "\~/Extensions/" followed by the path to the view inside of the project.

```c#
public class CountrySelector : drop-downContentFieldAttribute
{
    public CountrySelector() : base(new string[0])
    {
        this.Template = "~/Extensions/Views/ContentItemFields/CountrySelector.cshtml";
 
        var countries = DependencyLocator.Current.GetInstance<IUnitOfWorkFactory>().GetUnitOfWork().GetRepository<Country>().GetTable().OrderBy(o => o.Name).ToList();
        this.Options = countries.Select(o => new KeyValuePair<string, string>(o.Id.ToString(), o.Name)).ToArray();
    }
}
```

Then in the extensions project a razor view needs to exist at Views/ContentItemFields/CountrySelector.cshtml. This razor view needs to be an embedded resource. By default the extensions project will embed all razor views.

This example is a copy of the drop-down.cshtml view, with the @model declaration modified to use our new Extensions.CountrySelector.

```c#
@using Insite.ContentLibrary.ContentFields
@using Insite.WebFramework.ContentAdmin.Models.ContentItems
 
@model EditContentFieldModel<Extensions.CountrySelector> 
<label for="@Model.FieldName">    @Model.DisplayName
    @if (Model.ContentFieldAttribute.IsRequired)
    {
        <span class="required">(required)</span>    }
 
    @Html.Partial("ContentItemFields/_ContextDisplay", Model.ContentItemFieldModel)
</label><span data-valmsg-replace="true" data-valmsg-for="@(Model.FieldName)"></span><select id="@Model.FieldName" name="@Model.FieldName" @if (Model.ContentFieldAttribute.IsRequired) { <text> data-val="true" data-val-required="Value is required" </text> }>    <option value="">Select Value</option>    @foreach (var value in Model.ContentFieldAttribute.Options)
    {
        <option value="@value.Key" @(Model.GetValue().ToString() == value.Key ? "selected" : "")>@value.Value</option>    }
</select>
```

To make use of the new ContentFieldAttribute, add a new property to a custom widget. Then include your new attribute on the property. When editing this widget, the CountrySelector will be used.

```c#
[CountrySelector]
public string SelectedCountry
{
    get { return this.GetValue("SelectedCountry", string.Empty, FieldType.General); }
    set { this.SetValue("SelectedCountry", value, FieldType.General); }
```
