Complex Property
When you need to group multiple related fields together — like
street, city, and postal code for an address — you can use the
AddComplexProperty method.
This allows you to define a reusable structure that
keeps your models clean and organized. For example,
instead of adding separate address fields directly
to your main entity, you can create a single
Address
complex property that
contains all the related fields. This is perfect for
modeling things like contact details, metadata sections,
or any logical group of related inputs.
When you define a complex property, the framework
automatically generates a backing class (e.g.,
EmployeeAddress
) that implements
IBkComplexType
. You can define nested
fields inside it, each with its own UI configuration and
validation rules (like required fields or character limits).
These fields are rendered inside a <fieldset>
element in the edit form, keeping them visually grouped and
easy to work with.
publicpartialclassEmployee:IBkEntity<Employee,ApplicationDbContext>
{
publicvoidBkConfiguration(IBkEntityDesigner<Employee,ApplicationDbContext>designer)
{
// Note: This creates a complex property named Address using the internal class EmployeeAddress.// The nested fields (Country, City, Street, ZipCode) are fully configurable. designer.Properties.AddComplexProperty("Address","EmployeeAddress",p=>
{
// Sets the label for the entire complex section. p.Label("Address");
// Tooltip shown when hovering over the address group. p.ToolTip("Employee Address");
// Tab index for the entire complex group. p.TabIndex(2);
// Add nested text properties for the address fields: p.Properties.AddTextProperty<string>("Country",c=>
{
c.Label("Country");
c.PlaceHolder("Country");
c.ToolTip("Employee Country");
c.MaxLength(50);
c.MinLength(1);
c.TabIndex(1);
c.AutoComplete("country");
});
p.Properties.AddTextProperty<string>("City",c=>
{
c.Label("City");
c.PlaceHolder("City");
c.ToolTip("Employee City");
c.MaxLength(50);
c.MinLength(1);
c.TabIndex(2);
c.AutoComplete("city");
});
p.Properties.AddTextProperty<string>("Street",c=>
{
c.Label("Street");
c.PlaceHolder("Street");
c.ToolTip("Employee Street");
c.MaxLength(150);
c.MinLength(1);
c.TabIndex(3);
c.AutoComplete("street");
});
p.Properties.AddTextProperty<string>("ZipCode",c=>
{
c.Label("Zip Code");
c.PlaceHolder("Zip Code");
c.ToolTip("Employee Zip Code");
c.MaxLength(50);
c.MinLength(1);
c.TabIndex(4);
c.AutoComplete("zip-code");
});
});
}
}
How BlazorForKids handle configuration for Complex Property
publicclassConfiguration:IEntityTypeConfiguration<Employee>
{
publicvoidConfigure(EntityTypeBuilder<Employee>builder)
{
builder.ComplexProperty<EmployeeAddress>(a=>a.Address,complexType=>
{
complexType.Property(bk=>bk.Country).IsRequired(true).HasMaxLength(50);
complexType.Property(bk=>bk.City).IsRequired(true).HasMaxLength(50);
complexType.Property(bk=>bk.Street).IsRequired(true).HasMaxLength(150);
complexType.Property(bk=>bk.ZipCode).IsRequired(true).HasMaxLength(50);
});
//other configurations... }
}
When to Use Complex Properties
A complex property is best used when you want to group several related fields into a single, logical structure.
These are fields that, on their own, may not provide much value—but together they describe something meaningful.
A typical example is an address, where fields like Country
, City
, Street
,
and ZipCode
individually may not be very informative, but together represent a complete and valuable piece of data.
Complex properties are also a great choice for capturing settings, configurations, or preferences— especially when multiple fields are conceptually related and should be grouped in both the data model and the UI. This approach helps maintain a clean structure and improves the readability of forms and code.
How Complex Properties Work in BlazorForKids
When you use AddComplexProperty
, the BlazorForKids framework automatically generates a backing class
that implements IBkComplexType
. This generated class contains the fields you define (like Country
, City
, etc.),
and each property is decorated with validation and display metadata.
In the UI, the framework renders a grouped section of fields inside the form. These fields are tied to a single property of your main entity
(e.g., Address
) and are automatically handled during serialization, validation, and model binding.
Important Limitation: Reusability
Currently, BlazorForKids does not support reusing complex types across multiple entities.
If you want to use the same complex structure (e.g., an address) in more than one entity (such as Employee
and Customer
),
you must declare the complex property separately for each one.
- You must call
AddComplexProperty
in each entity where needed. - You must assign a unique class name for the complex type (e.g.,
EmployeeAddress
,CustomerAddress
). - You are responsible for keeping the structure of these complex classes consistent, if needed.
While this may introduce some duplication, it allows flexibility for each complex type to evolve independently in the future.
When Not to Use Complex Properties
Avoid using complex properties if the grouped fields are not logically related, or if your intent is to reuse the same group across many entities without duplication. In such scenarios, it may be more appropriate to model the group as a separate entity or to wait for full support of reusable complex types in a future release of the framework.