From 4d2e597c9d447b168919f5209114262e57c90da1 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 21 Jul 2026 11:43:30 +0800 Subject: [PATCH] Fix code samples and behavior descriptions in documentation --- .../framework/api-development/auto-controllers.md | 2 +- docs/en/framework/fundamentals/localization.md | 4 ++-- docs/en/framework/fundamentals/validation.md | 5 +++-- docs/en/framework/infrastructure/interceptors.md | 4 +++- docs/en/framework/ui/angular/list-service.md | 4 ++-- docs/en/modules/ai-management/index.md | 13 ++++++++++--- docs/en/modules/chat.md | 3 +++ docs/en/modules/cms-kit/comments.md | 2 +- docs/en/modules/docs.md | 4 ++-- docs/en/modules/gdpr.md | 3 +++ docs/en/modules/language-management.md | 1 + docs/en/modules/text-template-management.md | 3 +++ docs/en/multi-lingual-entities.md | 8 ++++++++ 13 files changed, 42 insertions(+), 14 deletions(-) diff --git a/docs/en/framework/api-development/auto-controllers.md b/docs/en/framework/api-development/auto-controllers.md index 3202592056..df5da8ed12 100644 --- a/docs/en/framework/api-development/auto-controllers.md +++ b/docs/en/framework/api-development/auto-controllers.md @@ -93,7 +93,7 @@ Then the route for getting a book will be '**/api/volosoft/book-store/book/{id}* * Normalization can be customized by setting the `UrlActionNameNormalizer` option. It's an action delegate that is called for every method. * If there is another parameter with 'Id' postfix, then it's also added to the route as the final route segment (like '/phoneId'). -The final controller name also removes suffixes configured in `AbpConventionalControllerOptions.IgnoredUrlSuffixesInControllerNames`. The default list contains `Integration`, so `PaymentIntegrationService` uses `payment` as its controller route name. You can replace the list when another suffix convention is required: +When the `UrlControllerNameNormalizer` option is not set, the final controller name also removes suffixes configured in `AbpConventionalControllerOptions.IgnoredUrlSuffixesInControllerNames` (a custom normalizer takes over the whole controller-name calculation and the ignored suffixes are not applied). The default list contains `Integration`, so `PaymentIntegrationService` uses `payment` as its controller route name. You can replace the list when another suffix convention is required: ```csharp Configure(options => diff --git a/docs/en/framework/fundamentals/localization.md b/docs/en/framework/fundamentals/localization.md index 2e0121c172..5d89973504 100644 --- a/docs/en/framework/fundamentals/localization.md +++ b/docs/en/framework/fundamentals/localization.md @@ -296,7 +296,7 @@ Contributors are order-sensitive. A lookup starts with the last registered contr Replace `IExternalLocalizationStore` when localization resources need to be discovered at runtime or loaded from an external system. The default `NullExternalLocalizationStore` does not provide any resources. -The string localizer factory first searches the resources registered in `AbpLocalizationOptions.Resources`. If it cannot find the requested resource name, it queries `IExternalLocalizationStore`. The store exposes synchronous and asynchronous methods for retrieving a resource by name, enumerating resource names and enumerating resources. +The string localizer factory first searches the resources registered in `AbpLocalizationOptions.Resources`. If it cannot find the requested resource name, it queries `IExternalLocalizationStore`. The store exposes synchronous and asynchronous methods for retrieving a resource by name, and asynchronous methods for enumerating resource names and resources. The factory caches the localizer after it resolves a resource name. Changing the resource object returned by the store does not make the factory resolve that name again. Use dynamic contributors when the localization values themselves need to change while the application is running. @@ -363,7 +363,7 @@ var serialized = localizableStringSerializer.Serialize( var localizableString = localizableStringSerializer.Deserialize(serialized!); ```` -The default serializer uses `L:,` for `LocalizableString` and `F:` for `FixedLocalizableString`. A value without a recognized prefix is deserialized as a `FixedLocalizableString`. An invalid `L:` value throws an `AbpException`. Serializing `null` returns `null`; serializing another `ILocalizableString` implementation throws an `AbpException`. +The default serializer uses `L:,` for `LocalizableString` and `F:` for `FixedLocalizableString`. A value without a recognized prefix is deserialized as a `FixedLocalizableString`; values too short to carry a prefix and a content (like the literal `L:`) are treated the same way. An `L:` value without a comma or with an empty key throws an `AbpException`. Serializing `null` returns `null`; serializing another `ILocalizableString` implementation throws an `AbpException`. ### Format Arguments diff --git a/docs/en/framework/fundamentals/validation.md b/docs/en/framework/fundamentals/validation.md index 2a05e60ad0..1c3cc0b265 100644 --- a/docs/en/framework/fundamentals/validation.md +++ b/docs/en/framework/fundamentals/validation.md @@ -142,16 +142,17 @@ public class InputClass } ```` -If a class has `[DisableValidation]`, add `[EnableValidation]` to a method to enable automatic method validation for that method: +If a class that is subject to automatic validation (it implements `IValidationEnabled`, like application services do) has `[DisableValidation]`, add `[EnableValidation]` to a method to re-enable automatic validation for that method (`[EnableValidation]` does not activate validation for a class that isn't intercepted at all): ````csharp [DisableValidation] -public class MyService +public class MyService : IValidationEnabled, ITransientDependency { [EnableValidation] public virtual Task UpdateAsync(MyInput input) { //... + return Task.CompletedTask; } } ```` diff --git a/docs/en/framework/infrastructure/interceptors.md b/docs/en/framework/infrastructure/interceptors.md index 25cf783108..b871ed6a1c 100644 --- a/docs/en/framework/infrastructure/interceptors.md +++ b/docs/en/framework/infrastructure/interceptors.md @@ -209,7 +209,9 @@ You can also disable ABP class interceptors for all registrations or for types s // Disable all class interceptors. context.Services.DisableAbpClassInterceptors(); -// Or disable them only for selected implementation types. +// Or disable them only for selected types. The predicate receives the +// exposed service type, which differs from the implementation type when +// a class is exposed through its interfaces or base classes. context.Services.DisableAbpClassInterceptors( new NamedTypeSelector( "MyHotPathServices", diff --git a/docs/en/framework/ui/angular/list-service.md b/docs/en/framework/ui/angular/list-service.md index bfa66cebb9..6c65ac6efc 100644 --- a/docs/en/framework/ui/angular/list-service.md +++ b/docs/en/framework/ui/angular/list-service.md @@ -16,10 +16,10 @@ `ListService` is **not provided in root**. The reason is, this way, it will clear any subscriptions on component destroy. You may use the optional `LIST_QUERY_DEBOUNCE_TIME` token to adjust the debounce behavior. ```ts -import { ListService } from '@abp/ng.core'; +import { LIST_QUERY_DEBOUNCE_TIME, ListService } from '@abp/ng.core'; import { BookDto } from '../models'; import { BookService } from '../services'; -import { inject } from '@angular/core'; +import { Component, inject } from '@angular/core'; @Component({ /* class metadata here */ diff --git a/docs/en/modules/ai-management/index.md b/docs/en/modules/ai-management/index.md index f9e15a7c9a..9ce3caf865 100644 --- a/docs/en/modules/ai-management/index.md +++ b/docs/en/modules/ai-management/index.md @@ -1013,8 +1013,9 @@ chatComponent.off('messageSent', callbackFunction); In order to configure the application to use the AI Management module, you first need to import `provideAIManagementConfig` from `@volo/abp.ng.ai-management/config` to root application configuration. Then, you will need to append it to the `appConfig` array: -```js +```ts // app.config.ts +import { ApplicationConfig } from '@angular/core'; import { provideAIManagementConfig } from '@volo/abp.ng.ai-management/config'; export const appConfig: ApplicationConfig = { @@ -1027,8 +1028,10 @@ export const appConfig: ApplicationConfig = { The AI Management module should be imported and lazy-loaded in your routing array. It has a `createRoutes` function for configuration and is available from `@volo/abp.ng.ai-management`. -```js +```ts // app.routes.ts +import { Routes } from '@angular/router'; + const APP_ROUTES: Routes = [ // ... { @@ -1207,6 +1210,8 @@ dotnet add package OllamaSharp Create a factory class that implements `IChatClientFactory`: ```csharp +using System; +using System.Threading.Tasks; using Microsoft.Extensions.AI; using OllamaSharp; using Volo.AIManagement.Factory; @@ -1272,9 +1277,11 @@ The `ChatClientCreationConfiguration` object provides the following properties f Here's an example of implementing a factory for Azure OpenAI: -Install the `Azure.AI.OpenAI` NuGet package before adding this factory. +Install the `Azure.AI.OpenAI` and `Microsoft.Extensions.AI.OpenAI` NuGet packages before adding this factory (the `AsIChatClient()` extension method comes from `Microsoft.Extensions.AI.OpenAI`). ```csharp +using System; +using System.Threading.Tasks; using Azure.AI.OpenAI; using Azure; using Microsoft.Extensions.AI; diff --git a/docs/en/modules/chat.md b/docs/en/modules/chat.md index 8c2128d990..f3d30691a7 100644 --- a/docs/en/modules/chat.md +++ b/docs/en/modules/chat.md @@ -237,6 +237,7 @@ In order to configure the application to use the chat module, you first need to ```ts // app.config.ts +import { ApplicationConfig } from '@angular/core'; import { provideChatConfig } from '@volo/abp.ng.chat/config'; export const appConfig: ApplicationConfig = { @@ -252,6 +253,8 @@ The chat module should be imported and lazy-loaded in your routing array. It exp ```ts // app.routes.ts +import { Routes } from '@angular/router'; + const APP_ROUTES: Routes = [ // ... { diff --git a/docs/en/modules/cms-kit/comments.md b/docs/en/modules/cms-kit/comments.md index 3dade384a6..5d1b614570 100644 --- a/docs/en/modules/cms-kit/comments.md +++ b/docs/en/modules/cms-kit/comments.md @@ -45,7 +45,7 @@ Configure(options => - `EntityTypes`: List of defined entity types (`CommentEntityTypeDefinition`) in the comment system. - `IsRecaptchaEnabled`: This flag enables or disables the reCaptcha for the comment system. You can set it as **true** if you want to use reCaptcha in your comment system. -- `AllowedExternalUrls`: The allowed external URLs for each entity type. When it is specified for an entity type, every external URL detected in a comment text is checked against the configured values, and the comment is rejected when a URL doesn't match any of them. +- `AllowedExternalUrls`: The allowed external URLs for each entity type. When it is specified for an entity type, a comment is rejected when it contains an external URL that doesn't include any of the configured values. The check is a case-insensitive substring comparison of the normalized URLs (`www.` prefixes and trailing slashes are ignored), not an exact origin match. `CommentEntityTypeDefinition` properties: diff --git a/docs/en/modules/docs.md b/docs/en/modules/docs.md index a9307733e7..a0a9b4b137 100644 --- a/docs/en/modules/docs.md +++ b/docs/en/modules/docs.md @@ -35,7 +35,7 @@ The Docs module supports Entity Framework Core and MongoDB. From the solution di abp add-module Volo.Docs ``` -For an Entity Framework Core solution, the command adds `builder.ConfigureDocs()` to the migrations `DbContext`, creates a migration and runs the database migrator. Use `--skip-db-migrations` when you want to manage that step yourself. MongoDB does not require an EF Core migration. +For an Entity Framework Core solution with a conventional layered structure, the command adds `builder.ConfigureDocs()` to the `DbContext` in the `.EntityFrameworkCore` (or `.DbMigrations`) project, creates a migration and runs the `DbMigrator` project. When the solution doesn't contain these projects (for example, a single-layer solution), configure the model and apply the migration yourself. Use `--skip-db-migrations` when you want to manage that step yourself. MongoDB does not require an EF Core migration. For a manual installation, add the Docs packages and module dependencies that correspond to each application layer. MVC/Razor Pages hosts also need the `@abp/docs` package. Keep every package on the same version as the rest of your ABP solution, then run `abp install-libs` in the web project. @@ -61,7 +61,7 @@ The main project fields are: * **MainWebsiteUrl**: Target of the project logo. * **LatestVersionBranchName**: Branch used for the latest documentation. -Deleting a project removes only the project record. Before deleting it, remove its cached documents through document administration, verify and remove its Elasticsearch entries when search is enabled, and delete every generated PDF through **Manage PDF Files** so the BLOB objects are deleted. The project delete operation does not perform these cleanup steps automatically. +Deleting a project deletes the project record and its PDF file metadata, but nothing else. Before deleting it, remove its cached documents through document administration, verify and remove its Elasticsearch entries when search is enabled, and delete every generated PDF through **Manage PDF Files** so the BLOB objects are deleted. The project delete operation does not perform these cleanup steps automatically. The public UI starts at `/documents`. You can change this route with `DocsUiOptions.RoutePrefix`, as shown in the [UI options](#ui-options) section. diff --git a/docs/en/modules/gdpr.md b/docs/en/modules/gdpr.md index 8689791963..e385d82442 100644 --- a/docs/en/modules/gdpr.md +++ b/docs/en/modules/gdpr.md @@ -192,6 +192,7 @@ To configure the application to use the GDPR module, import `provideGdprConfig` ```ts // app.config.ts +import { ApplicationConfig } from '@angular/core'; import { provideGdprConfig, withCookieConsentOptions, @@ -215,6 +216,8 @@ The GDPR module should be imported and lazy-loaded in your routing array. It exp ```ts // app.routes.ts +import { Routes } from '@angular/router'; + const APP_ROUTES: Routes = [ // other route definitions { diff --git a/docs/en/modules/language-management.md b/docs/en/modules/language-management.md index 1596afdbd1..22d249290d 100644 --- a/docs/en/modules/language-management.md +++ b/docs/en/modules/language-management.md @@ -235,6 +235,7 @@ The language management module should be imported and lazy-loaded in your routin ```ts // app.routes.ts +import { Routes } from '@angular/router'; const APP_ROUTES: Routes = [ // ... diff --git a/docs/en/modules/text-template-management.md b/docs/en/modules/text-template-management.md index dc9479593a..6941ec34af 100644 --- a/docs/en/modules/text-template-management.md +++ b/docs/en/modules/text-template-management.md @@ -220,6 +220,7 @@ To configure the application to use the text template management module, import ```ts // app.config.ts +import { ApplicationConfig } from '@angular/core'; import { provideTextTemplateManagementConfig } from '@volo/abp.ng.text-template-management/config'; export const appConfig: ApplicationConfig = { @@ -234,6 +235,8 @@ The text template management module should be imported and lazy-loaded in your r ```ts // app.routes.ts +import { Routes } from '@angular/router'; + const APP_ROUTES: Routes = [ // ... { diff --git a/docs/en/multi-lingual-entities.md b/docs/en/multi-lingual-entities.md index f3c8602269..43e93247f4 100644 --- a/docs/en/multi-lingual-entities.md +++ b/docs/en/multi-lingual-entities.md @@ -20,6 +20,9 @@ abp add-package Volo.Abp.MultiLingualObject Add `AbpMultiLingualObjectsModule` as a dependency of that module when the package is installed manually: ````csharp +using Volo.Abp.Modularity; +using Volo.Abp.MultiLingualObjects; + [DependsOn(typeof(AbpMultiLingualObjectsModule))] public class MyApplicationModule : AbpModule { @@ -31,6 +34,7 @@ public class MyApplicationModule : AbpModule Implement `IMultiLingualObject` on the object and `IObjectTranslation` on its translation type: ```csharp +using System.Collections.Generic; using Volo.Abp.MultiLingualObjects; public class Product : IMultiLingualObject @@ -54,6 +58,10 @@ public class ProductTranslation : IObjectTranslation Inject `IMultiLingualObjectManager` and call `GetTranslationAsync`: ```csharp +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiLingualObjects; + public class ProductService : ITransientDependency {