ISul.Web.Core
2026.10.1.4
dotnet add package ISul.Web.Core --version 2026.10.1.4
NuGet\Install-Package ISul.Web.Core -Version 2026.10.1.4
<PackageReference Include="ISul.Web.Core" Version="2026.10.1.4" />
<PackageVersion Include="ISul.Web.Core" Version="2026.10.1.4" />
<PackageReference Include="ISul.Web.Core" />
paket add ISul.Web.Core --version 2026.10.1.4
#r "nuget: ISul.Web.Core, 2026.10.1.4"
#:package ISul.Web.Core@2026.10.1.4
#addin nuget:?package=ISul.Web.Core&version=2026.10.1.4
#tool nuget:?package=ISul.Web.Core&version=2026.10.1.4
ISul Web Package
Formulários dinâmicos com DynamicContent
As classes do namespace ISul.Web.DynamicContent geram um schema JSON a partir de propriedades C# anotadas. Esse schema pode ser enviado ao frontend para que ele escolha o componente de cada campo, aplique validações e monte o formulário.
1. Defina o conteúdo editável
using ISul.Web.DynamicContent;
public sealed class HomeContent {
[DynamicContent("title", DynamicContentType.Text, "Título", max: 120, required: true)]
public string Title { get; set; } = "";
[DynamicContent(DynamicContentType.Text, Label = "Descrição", Max = 500)]
public string? Description { get; set; }
[DynamicContent(DynamicContentType.Image, Label = "Imagem principal", Required = true)]
public string ImageUrl { get; set; } = "";
[DynamicContent(Label = "Publicar em")]
public DateTimeOffset? PublishedAt { get; set; }
[DynamicContent(DynamicContentType.List, Label = "Ações", Min = 1, Max = 3)]
public ActionContent[] Actions { get; set; } = [];
}
public sealed class ActionContent {
[DynamicContent(Label = "Texto", Max = 40, Required = true)]
public string Label { get; set; } = "";
[DynamicContent(DynamicContentType.Url, Label = "Link", Required = true)]
public string Url { get; set; } = "";
}
Quando Type não é informado, ele é inferido a partir do tipo da propriedade. Use um DynamicContentType explícito para tipos sem representação C# própria, como Image, Icon e Url.
2. Exponha o schema pela API
O método de extensão pode ser usado diretamente em um endpoint ASP.NET Core:
using ISul.Web.DynamicContent;
app.MapGet("/api/content/home/schema", () =>
Results.Ok(typeof(HomeContent).GetDynamicContentSchema())
);
Também é possível injetar ou instanciar DynamicContentSchemaProvider e chamar GetSchema<HomeContent>().
Com as opções JSON padrão do ASP.NET Core, o endpoint retorna:
{
"name": "HomeContent",
"fields": [
{
"name": "title",
"label": "Título",
"type": "text",
"required": true,
"max": 120
},
{
"name": "description",
"label": "Descrição",
"type": "text",
"required": false,
"max": 500
},
{
"name": "imageUrl",
"label": "Imagem principal",
"type": "image",
"required": true
},
{
"name": "publishedAt",
"label": "Publicar em",
"type": "datetime",
"required": false
},
{
"name": "actions",
"label": "Ações",
"type": "list",
"required": false,
"min": 1,
"max": 3,
"fields": [
{
"name": "label",
"label": "Texto",
"type": "text",
"required": true,
"max": 40
},
{
"name": "url",
"label": "Link",
"type": "url",
"required": true
}
]
}
]
}
O schema descreve somente a estrutura do formulário. Os valores atuais do conteúdo podem ser enviados em outro objeto ou endpoint, usando os nomes definidos em fields[].name para associar cada valor ao campo correspondente.
3. Valide o JSON recebido
O mesmo schema pode validar o JsonElement enviado pelo frontend antes que o conteúdo seja persistido. A validação verifica:
- objeto JSON na raiz e ausência de campos desconhecidos;
- campos obrigatórios e valores em branco;
- tipos de texto, inteiro, decimal, booleano, data, data e hora, URL e lista;
- limites
MineMaxpara números, textos e quantidades de itens; - objetos e campos aninhados em listas.
using ISul.Web.DynamicContent;
using ISul.Web.DynamicContent.Metadata;
using System.Text.Json;
public sealed class ContentRequest {
public JsonElement? Data { get; set; }
}
app.MapPut("/api/content/home", (ContentRequest request) => {
DynamicContentSchema schema = typeof(HomeContent).GetDynamicContentSchema();
DynamicContentValidationResult validation = schema.Validate(request.Data);
if (!validation.IsValid) {
return Results.ValidationProblem(
validation.Errors
.GroupBy(error => error.Path)
.ToDictionary(
group => group.Key,
group => group.Select(error => error.Message).ToArray()
)
);
}
string json = request.Data!.Value.GetRawText();
// Persista json...
return Results.NoContent();
});
Os erros usam caminhos JSON, por exemplo $.title e $.actions[0].url. Um JSON serializado dentro de uma string é rejeitado: o frontend deve enviar data como objeto JSON, sem aplicar JSON.stringify ao campo isoladamente.
O tipo usado para obter o schema deve ser escolhido no servidor a partir de um identificador conhecido. Não aceite do frontend um schema arbitrário para validar o próprio conteúdo.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- HtmlAgilityPack (>= 1.13.0)
- ISul.Data.Core (>= 2026.10.1.4)
- ISul.Standard (>= 2026.10.1.4)
-
net8.0
- HtmlAgilityPack (>= 1.13.0)
- ISul.Data.Core (>= 2026.10.1.4)
- ISul.Standard (>= 2026.10.1.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|