@ -0,0 +1,13 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Account": "帳號",
|
||||
"Welcome": "歡迎",
|
||||
"UseOneOfTheFollowingLinksToContinue": "使用下面的連結繼續",
|
||||
"FrameworkHomePage": "框架首頁",
|
||||
"FrameworkDocumentation": "框架文件",
|
||||
"OfficialBlog": "官方部落格",
|
||||
"CommercialHomePage": "商業版首頁",
|
||||
"CommercialSupportWebSite": "商業版支援網站"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Permission:NpmPackages": "NPM套件",
|
||||
"Permission:NugetPackages": "Nuget套件",
|
||||
"Permission:Maintenance": "維護",
|
||||
"Permission:Maintain": "維護",
|
||||
"Permission:ClearCaches": "清除快取",
|
||||
"Permission:Modules": "模組",
|
||||
"Permission:Packages": "套件",
|
||||
"Permission:Edit": "編輯",
|
||||
"Permission:Delete": "刪除",
|
||||
"Permission:Create": "建立",
|
||||
"Menu:Packages": "套件",
|
||||
"NpmPackageDeletionWarningMessage": "該NPM套件將會被刪除. 你確定嗎?",
|
||||
"NugetPackageDeletionWarningMessage": "該Nuget套件將會被刪除. 你確定嗎?",
|
||||
"ModuleDeletionWarningMessage": "該模組將會被刪除. 你確定嗎?",
|
||||
"Name": "名稱",
|
||||
"DisplayName": "顯示名稱",
|
||||
"ShortDescription": "簡述",
|
||||
"NameFilter": "名稱",
|
||||
"CreationTime": "建立時間",
|
||||
"IsPro": "是否為專業版",
|
||||
"EfCoreConfigureMethodName": "設定方法",
|
||||
"IsProFilter": "是否為專業版",
|
||||
"ApplicationType": "應用程式類型",
|
||||
"Target": "目標",
|
||||
"TargetFilter": "目標",
|
||||
"ModuleClass": "模組分類",
|
||||
"NugetPackageTarget.DomainShared": "Domain Shared",
|
||||
"NugetPackageTarget.Domain": "Domain",
|
||||
"NugetPackageTarget.Application": "Application",
|
||||
"NugetPackageTarget.ApplicationContracts": "Application Contracts",
|
||||
"NugetPackageTarget.HttpApi": "Http Api",
|
||||
"NugetPackageTarget.HttpApiClient": "Http Api Client",
|
||||
"NugetPackageTarget.Web": "Web",
|
||||
"NugetPackageTarget.EntityFrameworkCore": "EntityFramework Core",
|
||||
"NugetPackageTarget.MongoDB": "MongoDB",
|
||||
"Edit": "編輯",
|
||||
"Delete": "刪除",
|
||||
"Refresh": "刷新",
|
||||
"NpmPackages": "NPM套件",
|
||||
"NugetPackages": "Nuget套件",
|
||||
"NpmPackageCount": "NPM套件數量",
|
||||
"NugetPackageCount": "Nuget套件數量",
|
||||
"Module": "模組",
|
||||
"ModuleInfo": "模組信息",
|
||||
"CreateANpmPackage": "建立NPM套件",
|
||||
"CreateAModule": "建立模組",
|
||||
"CreateANugetPackage": "建立Nuget套件",
|
||||
"AddNew": "建立",
|
||||
"PackageAlreadyExist{0}": "\"{0}\"已經被添加.",
|
||||
"ClearCache": "清除快取",
|
||||
"SuccessfullyCleared": "清除成功",
|
||||
"Menu:NpmPackages": "NPM套件",
|
||||
"Menu:Modules": "模組",
|
||||
"Menu:Maintenance": "維護",
|
||||
"Menu:NugetPackages": "Nuget套件"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Volo.AbpIo.Domain:010004": "超過最大成員數!",
|
||||
"Volo.AbpIo.Domain:010005": "超過最大擁有者數!",
|
||||
"Volo.AbpIo.Domain:010006": "使用者已經是該組織的擁有者!",
|
||||
"Volo.AbpIo.Domain:010007": "該使用者已經是該組織的開發者!",
|
||||
"Volo.AbpIo.Domain:010008": "允許的開發者數量不能低於當前開發者數量!",
|
||||
"Volo.AbpIo.Domain:010009": "允許的開發者數量不能小於零!",
|
||||
"Volo.AbpIo.Domain:010010": "超出了最大mac地址數!",
|
||||
"Volo.AbpIo.Domain:010011": "個人許可不允許超過1個開發者!",
|
||||
"Volo.AbpIo.Domain:010012": "許可過期後許可不可延長1個月!",
|
||||
"Volo.AbpIo.Domain:020001": "不能刪除該NPM套件因為\"{NugetPackages}\"Nuget套件依賴此套件.",
|
||||
"Volo.AbpIo.Domain:020002": "不能刪除該NPM套件因為\"{Modules}\"模組正在使用此套件.",
|
||||
"Volo.AbpIo.Domain:020003": "不能刪除該NPM套件因為\"{Modules}\"模組正在使用此套件並且\"{NugetPackages}\"Nuget套件依賴此套件.",
|
||||
"Volo.AbpIo.Domain:020004": "不能刪除該Nuget套件因為\"{Modules}\"模組正在使用此套件.",
|
||||
"WantToLearn?": "想學習嗎?",
|
||||
"ReadyToGetStarted?": "準備開始了嗎?",
|
||||
"JoinOurCommunity": "加入我們的社群",
|
||||
"GetStartedUpper": "開始",
|
||||
"ForkMeOnGitHub": "Fork me on GitHub",
|
||||
"Features": "功能",
|
||||
"GetStarted": "開始",
|
||||
"Documents": "文件",
|
||||
"Community": "社群",
|
||||
"ContributionGuide": "貢獻指南",
|
||||
"Blog": "部落格",
|
||||
"Commercial": "商業版",
|
||||
"SeeDocuments": "查看文件"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"OrganizationManagement": "組織管理",
|
||||
"OrganizationList": "組織列表",
|
||||
"Volo.AbpIo.Commercial:010003": "您不是該組織的擁有者!",
|
||||
"OrganizationNotFoundMessage": "找不到任何組織!",
|
||||
"DeveloperCount": "開發者數量",
|
||||
"Owners": "擁有者",
|
||||
"AddMember": "加入成員",
|
||||
"AddOwner": "加入擁有者",
|
||||
"AddDeveloper": "加入開發者",
|
||||
"UserName": "使用者名稱",
|
||||
"Name": "名稱",
|
||||
"EmailAddress": "電子信箱地址",
|
||||
"Developers": "開發者",
|
||||
"LicenseType": "許可證類型",
|
||||
"Manage": "管理",
|
||||
"StartDate": "開始日期",
|
||||
"EndDate": "結束日期",
|
||||
"Modules": "模組",
|
||||
"LicenseExtendMessage": "您的許可已經延長至{0}",
|
||||
"LicenseUpgradeMessage": "您的許可已升級為{0}",
|
||||
"LicenseAddDeveloperMessage": "{0}個開發者已加入到您的許可",
|
||||
"Volo.AbpIo.Commercial:010004": "不能找到指定的使用者! 使用者必須已經註冊.",
|
||||
"MyOrganizations": "我的組織",
|
||||
"ApiKey": "API key",
|
||||
"UserNameNotFound": "沒有使用者名稱為{0}的使用者"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
}
|
||||
}
|
||||
@ -1,74 +1,39 @@
|
||||
## Entity Framework Core PostgreSQL integrace
|
||||
# Přepnutí na EF Core PostgreSQL providera
|
||||
|
||||
> Podívejte se na [Entity Framework Core integrační dokument](../Entity-Framework-Core.md) pro základy integrace EF Core.
|
||||
Tento dokument vysvětluje, jak přepnout na poskytovatele databáze **PostgreSQL** pro **[spouštěcí šablonu aplikace](Startup-Templates/Application.md)**, která je dodávána s předem nakonfigurovaným SQL poskytovatelem.
|
||||
|
||||
### Aktualizace projektu EntityFrameworkCore
|
||||
## Výměna balíku Volo.Abp.EntityFrameworkCore.SqlServer
|
||||
|
||||
- V projektu `Acme.BookStore.EntityFrameworkCore` nahraďte balík `Volo.Abp.EntityFrameworkCore.SqlServer` za `Volo.Abp.EntityFrameworkCore.PostgreSql`
|
||||
- Aktualizace pro použití PostgreSQL v `BookStoreEntityFrameworkCoreModule`
|
||||
- Nahraďte `AbpEntityFrameworkCoreSqlServerModule` za `AbpEntityFrameworkCorePostgreSqlModule`
|
||||
- Nahraďte `options.UseSqlServer()` za `options.UsePostgreSql()`
|
||||
- V jiných projektech aktualizujte PostgreSQL connection string v nezbytných `appsettings.json` souborech
|
||||
- Více informací v [PostgreSQL connection strings](https://www.connectionstrings.com/postgresql/), v tomto dokumentu věnujte pozornost sekci `Npgsql`
|
||||
Projekt `.EntityFrameworkCore` v řešení závisí na NuGet balíku [Volo.Abp.EntityFrameworkCore.SqlServer](https://www.nuget.org/packages/Volo.Abp.EntityFrameworkCore.SqlServer). Odstraňte tento balík a přidejte stejnou verzi balíku [Volo.Abp.EntityFrameworkCore.PostgreSql](https://www.nuget.org/packages/Volo.Abp.EntityFrameworkCore.PostgreSql).
|
||||
|
||||
### Aktualizace projektu EntityFrameworkCore.DbMigrations
|
||||
- Aktualizace pro použití PostgreSQL v `XXXMigrationsDbContextFactory`
|
||||
- Nahraďte `new DbContextOptionsBuilder<XXXMigrationsDbContext>().UseSqlServer()` za `new DbContextOptionsBuilder<XXXMigrationsDbContext>().UseNpgsql()`
|
||||
## Nahrazení závislosti modulu
|
||||
|
||||
Najděte třídu ***YourProjectName*EntityFrameworkCoreModule** v projektu `.EntityFrameworkCore`, odstraňte `typeof(AbpEntityFrameworkCoreSqlServerModule)` z atributu `DependsOn`, přidejte `typeof(AbpEntityFrameworkCorePostgreSqlModule)` (také nahraďte `using Volo.Abp.EntityFrameworkCore.SqlServer;` za `using Volo.Abp.EntityFrameworkCore.PostgreSql;`).
|
||||
|
||||
### Odstranění stávajících migrací
|
||||
## UsePostgreSql()
|
||||
|
||||
Smažte všechny stavající migrační soubory (včetně `DbContextModelSnapshot`)
|
||||
Najděte volání `UseSqlServer()` v *YourProjectName*EntityFrameworkCoreModule.cs uvnitř projektu `.EntityFrameworkCore` a nahraďte za `UsePostgreSql()`.
|
||||
|
||||

|
||||
Najděte volání `UseSqlServer()` v *YourProjectName*MigrationsDbContextFactory.cs uvnitř projektu `.EntityFrameworkCore.DbMigrations` a nahraďte za `UseNpgsql()`.
|
||||
|
||||
### Znovu vygenerujte počáteční migraci
|
||||
> V závislosti na struktuře řešení můžete najít více volání `UseSqlServer()`, které je třeba změnit.
|
||||
|
||||
Nastavte správný spouštěcí projekt (obvykle web projekt)
|
||||
## Změna connection stringů
|
||||
|
||||

|
||||
PostgreSql connection stringy se od těch pro SQL Server liší. Je proto potřeba zkontrolovat všechny soubory `appsettings.json` v řešení a connection stringy v nich nahradit. Podívejte se na [connectionstrings.com](https://www.connectionstrings.com/postgresql/) pro více detailů o možnostech PostgreSql connection stringů.
|
||||
|
||||
Otevřete **Package Manager Console** (Tools -> Nuget Package Manager -> Package Manager Console), zvolte `.EntityFrameworkCore.DbMigrations` jako **Default project** a proveďte následující příkaz:
|
||||
Typicky je potřeba změnit `appsettings.json` v projektech `.DbMigrator` a `.Web` projects, ale to záleží na vaší struktuře řešení.
|
||||
|
||||
Proveďte příkaz `Add-Migration`:
|
||||
````
|
||||
PM> Add-Migration Initial
|
||||
````
|
||||
## Regenerace migrací
|
||||
|
||||
### Aktualizace databáze
|
||||
Startovací šablona používá [Entity Framework Core Code First migrace](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/). EF Core migrace závisí na zvoleném DBMS poskytovateli. Tudíž změna DBMS poskytovatele způsobí selhání migrace.
|
||||
* Smažte složku Migrations v projektu `.EntityFrameworkCore.DbMigrations` and znovu sestavte řešení.
|
||||
* Spusťte `Add-Migration "Initial"` v Package Manager Console (je nutné zvolit `.DbMigrator` (nebo `.Web`) projekt jako startovací projekt v Solution Explorer a zvolit projekt `.EntityFrameworkCore.DbMigrations` jako výchozí v Package Manager Console).
|
||||
|
||||
K vytvoření databáze máte dvě možnosti.
|
||||
Tímto vytvoříte migraci databáze se všemi nakonfigurovanými databázovými objekty (tabulkami).
|
||||
|
||||
#### Použití DbMigrator aplikace
|
||||
Spusťte projekt `.DbMigrator` k vytvoření databáze a vložení počátečních dat.
|
||||
|
||||
Řešení obsahuje konzolovou aplikaci (v tomto příkladu nazvanou `Acme.BookStore.DbMigrator`), která může vytvářet databáze, aplikovat migrace a vkládat seed data. Je užitečná jak pro vývojové, tak pro produkční prostředí.
|
||||
## Spuštění aplikace
|
||||
|
||||
> Projekt `.DbMigrator` má vlastní `appsettings.json`. Takže pokud jste změnili connection string uvedený výše, musíte změnit také tento.
|
||||
|
||||
Klikněte pravým na projekt `.DbMigrator` a vyberte **Set as StartUp Project**:
|
||||
|
||||

|
||||
|
||||
Zmáčkněte F5 (nebo Ctrl+F5) ke spuštění aplikace. Výstup bude vypadat následovně:
|
||||
|
||||

|
||||
|
||||
#### Použití EF Core Update-Database příkazu
|
||||
|
||||
Ef Core má `Update-Database` příkaz, který v případě potřeby vytvoří databázi a aplikuje čekající migrace.
|
||||
|
||||
Nastavte správný spouštěcí projekt (obvykle web projekt)
|
||||
|
||||

|
||||
|
||||
Otevřete **Package Manager Console** (Tools -> Nuget Package Manager -> Package Manager Console), vyberte projekt `.EntityFrameworkCore.DbMigrations` jako **Default Project** and spusťte následující příkaz:
|
||||
|
||||
````
|
||||
PM> Update-Database
|
||||
````
|
||||
|
||||
Dojde k vytvoření nové databáze na základě nakonfigurovaného connection stringu.
|
||||
|
||||

|
||||
|
||||
> Použití nástroje `.DbMigrator` je doporučený způsob, jelikož zároveň vloží seed data nutné k správnému běhu webové aplikace.
|
||||
Vše je připraveno. Stačí už jen spustit aplikaci a užívat si kódování.
|
||||
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
@ -0,0 +1,3 @@
|
||||
## Ambient Context Pattern
|
||||
|
||||
TODO
|
||||
@ -1,3 +1,372 @@
|
||||
# Audit Logging
|
||||
|
||||
TODO
|
||||
[Wikipedia](https://en.wikipedia.org/wiki/Audit_trail): "*An audit trail (also called **audit log**) is a security-relevant chronological record, set of records, and/or destination and source of records that provide documentary evidence of the sequence of activities that have affected at any time a specific operation, procedure, or event*".
|
||||
|
||||
ABP Framework provides an **extensible audit logging system** that automates the audit logging by **convention** and provides **configuration** points to control the level of the audit logs.
|
||||
|
||||
An **audit log object** (see the Audit Log Object section below) is typically created & saved per web request. It includes;
|
||||
|
||||
* **Request & response details** (like URL, Http method, Browser info, HTTP status code... etc.).
|
||||
* **Performed actions** (controller actions and application service method calls with their parameters).
|
||||
* **Entity changes** occurred in the web request.
|
||||
* **Exception** information (if there was an error while executing the request).
|
||||
* **Request duration** (to measure the performance of the application).
|
||||
|
||||
> [Startup templates](Startup-Templates/Index.md) are configured for the audit logging system which is suitable for most of the applications. Use this document for a detailed control over the audit log system.
|
||||
|
||||
### Database Provider Support
|
||||
|
||||
* Fully supported by the [Entity Framework Core](Entity-Framework-Core.md) provider.
|
||||
* Entity change logging is not supported by the [MongoDB](MongoDB.md) provider. Other features work as expected.
|
||||
|
||||
## UseAuditing()
|
||||
|
||||
`UseAuditing()` middleware should be added to the ASP.NET Core request pipeline in order to create and save the audit logs. If you've created your applications using [the startup templates](Startup-Templates/Index.md), it is already added.
|
||||
|
||||
## AbpAuditingOptions
|
||||
|
||||
`AbpAuditingOptions` is the main [options object](Options.md) to configure the audit log system. You can configure it in the `ConfigureServices` method of your [module](Module-Development-Basics.md):
|
||||
|
||||
````csharp
|
||||
Configure<AbpAuditingOptions>(options =>
|
||||
{
|
||||
options.IsEnabled = false; //Disables the auditing system
|
||||
});
|
||||
````
|
||||
|
||||
Here, a list of the options you can configure:
|
||||
|
||||
* `IsEnabled` (default: `true`): A root switch to enable or disable the auditing system. Other options is not used if this value is `false`.
|
||||
* `HideErrors` (default: `true`): Audit log system hides and write regular [logs](Logging.md) if any error occurs while saving the audit log objects. If saving the audit logs is critical for your system, set this to `false` to throw exception in case of hiding the errors.
|
||||
* `IsEnabledForAnonymousUsers` (default: `true`): If you want to write audit logs only for the authenticated users, set this to `false`. If you save audit logs for anonymous users, you will see `null` for `UserId` values for these users.
|
||||
* `IsEnabledForGetRequests` (default: `false`): HTTP GET requests should not make any change in the database normally and audit log system doesn't save audit log objects for GET request. Set this to `true` to enable it also for the GET requests.
|
||||
* `ApplicationName`: If multiple applications saving audit logs into a single database, set this property to your application name, so you can distinguish the logs of different applications.
|
||||
* `IgnoredTypes`: A list of `Type`s to be ignored for audit logging. If this is an entity type, changes for this type of entities will not be saved. This list is also used while serializing the action parameters.
|
||||
* `EntityHistorySelectors`: A list of selectors those are used to determine if an entity type is selected for saving the entity change. See the section below for details.
|
||||
* `Contributors`: A list of `AuditLogContributor` implementations. A contributor is a way of extending the audit log system. See the "Audit Log Contributors" section below.
|
||||
|
||||
### Entity History Selectors
|
||||
|
||||
Saving all changes of all your entities would require a lot of database space. For this reason, **audit log system doesn't save any change for the entities unless you explicitly configure it**.
|
||||
|
||||
To save all changes of all entities, simply use the `AddAllEntities()` extension method.
|
||||
|
||||
````csharp
|
||||
Configure<AbpAuditingOptions>(options =>
|
||||
{
|
||||
options.EntityHistorySelectors.AddAllEntities();
|
||||
});
|
||||
````
|
||||
|
||||
`options.EntityHistorySelectors` actually a list of type predicate. You can write a lambda expression to define your filter.
|
||||
|
||||
The example selector below does the same of the `AddAllEntities()` extension method defined above:
|
||||
|
||||
````csharp
|
||||
Configure<AbpAuditingOptions>(options =>
|
||||
{
|
||||
options.EntityHistorySelectors.Add(
|
||||
new NamedTypeSelector(
|
||||
"MySelectorName",
|
||||
type =>
|
||||
{
|
||||
if (typeof(IEntity).IsAssignableFrom(type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
````
|
||||
|
||||
The condition `typeof(IEntity).IsAssignableFrom(type)` will be `true` for any class implements the `IEntity` interface (this is technically all the entities in your application). You can conditionally check and return `true` or `false` based on your preference.
|
||||
|
||||
`options.EntityHistorySelectors` is a flexible and dynamic way of selecting the entities for audit logging. Another way is to use the `Audited` and `DisableAuditing` attributes per entity.
|
||||
|
||||
## Enabling/Disabling Audit Logging for Services
|
||||
|
||||
### Enable/Disable for Controllers & Actions
|
||||
|
||||
All the controller actions are logged by default (see `IsEnabledForGetRequests` above for GET requests).
|
||||
|
||||
You can use the `[DisableAuditing]` to disable it for a specific controller type:
|
||||
|
||||
````csharp
|
||||
[DisableAuditing]
|
||||
public class HomeController : AbpController
|
||||
{
|
||||
//...
|
||||
}
|
||||
````
|
||||
|
||||
Use `[DisableAuditing]` for any action to control it in the action level:
|
||||
|
||||
````csharp
|
||||
public class HomeController : AbpController
|
||||
{
|
||||
[DisableAuditing]
|
||||
public async Task<ActionResult> Home()
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
public async Task<ActionResult> OtherActionLogged()
|
||||
{
|
||||
//...
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
### Enable/Disable for Application Services & Methods
|
||||
|
||||
[Application service](Application-Services.md) method calls also included into the audit log by default. You can use the `[DisableAuditing]` in service or method level.
|
||||
|
||||
#### Enable/Disable for Other Services
|
||||
|
||||
Action audit logging can be enabled for any type of class (registered to and resolved from the [dependency injection](Dependency-Injection.md)) while it is only enabled for the controllers and the application services by default.
|
||||
|
||||
Use `[Audited]` and `[DisableAuditing]` for any class or method that need to be audit logged. In addition, your class can (directly or inherently) implement the `IAuditingEnabled` interface to enable the audit logging for that class by default.
|
||||
|
||||
### Enable/Disable for Entities & Properties
|
||||
|
||||
An entity is ignored on entity change audit logging in the following cases;
|
||||
|
||||
* If you add an entity type to the `AbpAuditingOptions.IgnoredTypes` (as explained before), it is completely ignored in the audit logging system.
|
||||
* If the object is not an [entity](Entities.md) (not implements `IEntity` directly or inherently - All entities implement this interface by default).
|
||||
* If entity type is not public.
|
||||
|
||||
Otherwise, you can use `Audited` to enable entity change audit logging for an entity:
|
||||
|
||||
````csharp
|
||||
[Audited]
|
||||
public class MyEntity : Entity<Guid>
|
||||
{
|
||||
//...
|
||||
}
|
||||
````
|
||||
|
||||
Or disable it for an entity:
|
||||
|
||||
````csharp
|
||||
[DisableAuditing]
|
||||
public class MyEntity : Entity<Guid>
|
||||
{
|
||||
//...
|
||||
}
|
||||
````
|
||||
|
||||
Disabling audit logging can be necessary only if the entity is being selected by the `AbpAuditingOptions.EntityHistorySelectors` that explained before.
|
||||
|
||||
You can disable auditing only some properties of your entities for a detailed control over the audit logging:
|
||||
|
||||
````csharp
|
||||
[Audited]
|
||||
public class MyUser : Entity<Guid>
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Email { get; set; }
|
||||
|
||||
[DisableAuditing] //Ignore the Passoword on audit logging
|
||||
public string Password { get; set; }
|
||||
}
|
||||
````
|
||||
|
||||
Audit log system will save changes for the `MyUser` entity while it ignores the `Password` property which can be dangerous to save for security purposes.
|
||||
|
||||
In some cases, you may want to save a few properties but ignore all others. Writing `[DisableAuditing]` for all the other properties would be tedious. In such cases, use `[Audited]` only for the desired properties and mark the entity with the `[DisableAuditing]` attribute:
|
||||
|
||||
````csharp
|
||||
[DisableAuditing]
|
||||
public class MyUser : Entity<Guid>
|
||||
{
|
||||
[Audited] //Only log the Name change
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Email { get; set; }
|
||||
|
||||
public string Password { get; set; }
|
||||
}
|
||||
````
|
||||
|
||||
## IAuditingStore
|
||||
|
||||
`IAuditingStore` is an interface that is used to save the audit log objects (explained below) by the ABP Framework. If you need to save the audit log objects to a custom data store, you can implement the `IAuditingStore` in your own application and replace using the [dependency injection system](Dependency-Injection.md).
|
||||
|
||||
`SimpleLogAuditingStore` is used if no audit store was registered. It simply writes the audit object to the standard [logging system](Logging.md).
|
||||
|
||||
[The Audit Logging Module](Modules/Audit-Logging.md) has been configured in [the startup templates](Startup-Templates/Index.md) saves audit log objects to a database (it supports multiple database providers). So, most of the times you don't care about how `IAuditingStore` was implemented and used.
|
||||
|
||||
## Audit Log Object
|
||||
|
||||
An **audit log object** is created for each **web request** by default. An audit log object can be represented by the following relation diagram:
|
||||
|
||||

|
||||
|
||||
* **AuditLogInfo**: The root object with the following properties:
|
||||
* `ApplicationName`: When you save audit logs of different applications to the same database, this property is used to distinguish the logs of the applications.
|
||||
* `UserId`: Id of the current user, if the user has logged in.
|
||||
* `UserName`: User name of the current user, if the user has logged in (this value is here to not depend on the identity module/system for lookup).
|
||||
* `TenantId`: Id of the current tenant, for a multi-tenant application.
|
||||
* `TenantName`: Name of the current tenant, for a multi-tenant application.
|
||||
* `ExecutionTime`: The time when this audit log object has been created.
|
||||
* `ExecutionDuration`: Total execution duration of the request, in milliseconds. This can be used to observe the performance of the application.
|
||||
* `ClientId`: Id of the current client, if the client has been authenticated. A client is generally a 3rd-party application using the system over an HTTP API.
|
||||
* `ClientName`: Name of the current client, if available.
|
||||
* `ClientIpAddress`: IP address of the client/user device.
|
||||
* `CorrelationId`: Current [Correlation Id](CorrelationId.md). Correlation Id is used to relate the audit logs written by different applications (or microservices) in a single logical operation.
|
||||
* `BrowserInfo`: Browser name/version info of the current user, if available.
|
||||
* `HttpMethod`: HTTP method of the current request (GET, POST, PUT, DELETE... etc.).
|
||||
* `HttpStatusCode`: HTTP response status code for this request.
|
||||
* `Url`: URL of the request.
|
||||
* **AuditLogActionInfo**: An audit log action is typically a controller action or an [application service](Application-Services.md) method call during the web request. One audit log may contain multiple actions. An action object has the following properties:
|
||||
* `ServiceName`: Name of the executed controller/service.
|
||||
* `MethodName`: Name of the executed method of the controller/service.
|
||||
* `Parameters`: A JSON formatted text representing the parameters passed to the method.
|
||||
* `ExecutionTime`: The time when this method was executed.
|
||||
* `ExecutionDuration`: Duration of the method execution, in milliseconds. This can be used to observe the performance of the method.
|
||||
* **EntityChangeInfo**: Represents a change of an entity in this web request. An audit log may contain zero or more entity changes. An entity change has the following properties:
|
||||
* `ChangeTime`: The time when the entity was changed.
|
||||
* `ChangeType`: An enum with the following fields: `Created` (0), `Updated` (1) and `Deleted` (2).
|
||||
* `EntityId`: Id of the entity that was changed.
|
||||
* `EntityTenantId`: Id of the tenant this entity belongs to.
|
||||
* `EntityTypeFullName`: Type (class) name of the entity with full namespace (like *Acme.BookStore.Book* for the Book entity).
|
||||
* **EntityPropertyChangeInfo**: Represents a change of a property of an entity. An entity change info (explained above) may contain one or more property change with the following properties:
|
||||
* `NewValue`: New value of the property. It is `null` if the entity was deleted.
|
||||
* `OriginalValue`: Old/original value before the change. It is `null` if the entity was newly created.
|
||||
* `PropertyName`: The name of the property on the entity class.
|
||||
* `PropertyTypeFullName`: Type (class) name of the property with full namespace.
|
||||
* **Exception**: An audit log object may contain zero or more exception. In this way, you can get a report of the failed requests.
|
||||
* **Comment**: An arbitrary string value to add custom messages to the audit log entry. An audit log object may contain zero or more comments.
|
||||
|
||||
In addition to the standard properties explained above, `AuditLogInfo`, `AuditLogActionInfo` and `EntityChangeInfo` objects implement the `IHasExtraProperties` interface, so you can add custom properties to these objects.
|
||||
|
||||
## Audit Log Contributors
|
||||
|
||||
You can extend the auditing system by creating a class that is derived from the `AuditLogContributor` class which defines the `PreContribute` and the `PostContribute` methods.
|
||||
|
||||
The only pre-built contributor is the `AspNetCoreAuditLogContributor` class which sets the related properties for an HTTP request.
|
||||
|
||||
A contributor can set properties and collections of the `AuditLogInfo` class to add more information.
|
||||
|
||||
Example:
|
||||
|
||||
````csharp
|
||||
public class MyAuditLogContributor : AuditLogContributor
|
||||
{
|
||||
public override void PreContribute(AuditLogContributionContext context)
|
||||
{
|
||||
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
|
||||
context.AuditInfo.SetProperty(
|
||||
"MyCustomClaimValue",
|
||||
currentUser.FindClaimValue("MyCustomClaim")
|
||||
);
|
||||
}
|
||||
|
||||
public override void PostContribute(AuditLogContributionContext context)
|
||||
{
|
||||
context.AuditInfo.Comments.Add("Some comment...");
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
* `context.ServiceProvider` can be used to resolve services from the [dependency injection](Dependency-Injection.md).
|
||||
* `context.AuditInfo` can be used to access to the current audit log object to manipulate it.
|
||||
|
||||
After creating such a contributor, you must add it to the `AbpAuditingOptions.Contributors` list:
|
||||
|
||||
````csharp
|
||||
Configure<AbpAuditingOptions>(options =>
|
||||
{
|
||||
options.Contributors.Add(new MyAuditLogContributor());
|
||||
});
|
||||
````
|
||||
|
||||
## IAuditLogScope & IAuditingManager
|
||||
|
||||
This section explains the `IAuditLogScope` & `IAuditingManager` services for advanced use cases.
|
||||
|
||||
An **audit log scope** is an [ambient scope](Ambient-Context-Pattern.md) that **builds** and **saves** an audit log object (explained before). By default, an audit log scope is created for a web request by the Audit Log Middleware (see `UseAuditing()` section above).
|
||||
|
||||
### Access to the Current Audit Log Scope
|
||||
|
||||
Audit log contributors, was explained above, is a global way of manipulating the audit log object. It is good if you can get a value from a service.
|
||||
|
||||
If you need to manipulate the audit log object in an arbitrary point of your application, you can access to the current audit log scope and get the current audit log object (independent of how the scope is managed). Example:
|
||||
|
||||
````csharp
|
||||
public class MyService : ITransientDependency
|
||||
{
|
||||
private readonly IAuditingManager _auditingManager;
|
||||
|
||||
public MyService(IAuditingManager auditingManager)
|
||||
{
|
||||
_auditingManager = auditingManager;
|
||||
}
|
||||
|
||||
public async Task DoItAsync()
|
||||
{
|
||||
var currentAuditLogScope = _auditingManager.Current;
|
||||
if (currentAuditLogScope != null)
|
||||
{
|
||||
currentAuditLogScope.Log.Comments.Add(
|
||||
"Executed the MyService.DoItAsync method :)"
|
||||
);
|
||||
|
||||
currentAuditLogScope.Log.SetProperty("MyCustomProperty", 42);
|
||||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
Always check if `_auditingManager.Current` is null or not, because it is controlled in an outer scope and you can't know if an audit log scope was created before calling your method.
|
||||
|
||||
### Manually Create an Audit Log Scope
|
||||
|
||||
You rarely need to create a manual audit log scope, but if you need, you can create an audit log scope using the `IAuditingManager` as like in the following example:
|
||||
|
||||
````csharp
|
||||
public class MyService : ITransientDependency
|
||||
{
|
||||
private readonly IAuditingManager _auditingManager;
|
||||
|
||||
public MyService(IAuditingManager auditingManager)
|
||||
{
|
||||
_auditingManager = auditingManager;
|
||||
}
|
||||
|
||||
public async Task DoItAsync()
|
||||
{
|
||||
using (var auditingScope = _auditingManager.BeginScope())
|
||||
{
|
||||
try
|
||||
{
|
||||
//Call other services...
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//Add exceptions
|
||||
_auditingManager.Current.Log.Exceptions.Add(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
//Always save the log
|
||||
await auditingScope.SaveAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
You can call other services, they may call others, they may change entities and so on. All these interactions are saved as a single audit log object in the finally block.
|
||||
|
||||
## The Audit Logging Module
|
||||
|
||||
The Audit Logging Module basically implements the `IAuditingStore` to save the audit log objects to a database. It supports multiple database providers. This module is added to the startup templates by default.
|
||||
|
||||
See [the Audit Logging Module document](Modules/Audit-Logging.md) for more about it.
|
||||
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 2.7 MiB |
@ -0,0 +1,7 @@
|
||||
# Audit Logging Module
|
||||
|
||||
The Audit Logging Module basically implements the `IAuditingStore` to save the audit log objects to a database.
|
||||
|
||||
> Audit Logging module is already installed and configured for [the startup templates](../Startup-Templates/Index.md). So, most of the times you don't need to manually add this module to your application.
|
||||
|
||||
See [the audit logging system](../Audit-Logging.md) document for more about the audit logging.
|
||||
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 2.7 MiB |
@ -1,3 +1,59 @@
|
||||
# FluentValidation 集成
|
||||
|
||||
TODO
|
||||
ABP[验证](Validation.md)基础设施是可扩展的. [Volo.Abp.FluentValidation](https://www.nuget.org/packages/Volo.Abp.FluentValidation) NuGet 包扩展了验证系统使其与[FluentValidation](https://fluentvalidation.net/)库一起工作.
|
||||
|
||||
## 安装
|
||||
|
||||
建议使用[ABP CLI](CLI.md)安装包.
|
||||
|
||||
### 使用ABP CLI
|
||||
|
||||
在项目(.csproj文件)的文件夹中打开命令行窗口并输入以下命令:
|
||||
|
||||
````bash
|
||||
abp add-package Volo.Abp.FluentValidation
|
||||
````
|
||||
|
||||
### 手动安装
|
||||
|
||||
如果你想手动安装;
|
||||
|
||||
1. 添加 [Volo.Abp.FluentValidation](https://www.nuget.org/packages/Volo.Abp.FluentValidation) NuGet包到你的项目:
|
||||
|
||||
````
|
||||
Install-Package Volo.Abp.FluentValidation
|
||||
````
|
||||
|
||||
2. 添加 `AbpFluentValidationModule` 到你的模块的依赖列表:
|
||||
|
||||
````csharp
|
||||
[DependsOn(
|
||||
//...other dependencies
|
||||
typeof(AbpFluentValidationModule) //Add the FluentValidation module
|
||||
)]
|
||||
public class YourModule : AbpModule
|
||||
{
|
||||
}
|
||||
````
|
||||
|
||||
## 使用 FluentValidation
|
||||
|
||||
按照 [FluentValidation文档](https://fluentvalidation.net/) 创建验证器类.
|
||||
例如:
|
||||
|
||||
````csharp
|
||||
public class CreateUpdateBookDtoValidator : AbstractValidator<CreateUpdateBookDto>
|
||||
{
|
||||
public CreateUpdateBookDtoValidator()
|
||||
{
|
||||
RuleFor(x => x.Name).Length(3, 10);
|
||||
RuleFor(x => x.Price).ExclusiveBetween(0.0f, 999.0f);
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
ABP会自动找到这个类并在对象验证时与 `CreateUpdateBookDto` 关联.
|
||||
|
||||
## 另请参阅
|
||||
|
||||
* [验证系统](Validation.md)
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"GivenTenantIsNotAvailable": "指定的租戶不可用: {0}",
|
||||
"SwitchTenant": "切換租戶",
|
||||
"Name": "名稱",
|
||||
"SwitchTenantHint": "將name欄位留空以切換到主控端.",
|
||||
"Tenant": "租戶",
|
||||
"Switch": "切換",
|
||||
"NotSelected": "尚未選定"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"MaxResultCountExceededExceptionMessage": "{0}禁止超過{1}! 請在伺服器端增加{2}.{3}以獲得更多結果."
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
{
|
||||
"culture": "cs",
|
||||
"texts": {
|
||||
"DisplayName:Abp.Mailing.DefaultFromAddress": "Výchozí adresa odesílatele",
|
||||
"DisplayName:Abp.Mailing.DefaultFromDisplayName": "Výchozí zobrazované jméno odesilátele",
|
||||
"DisplayName:Abp.Mailing.Smtp.Host": "Hostitel",
|
||||
"DisplayName:Abp.Mailing.Smtp.Port": "Port",
|
||||
"DisplayName:Abp.Mailing.Smtp.UserName": "Uživatelské jméno",
|
||||
"DisplayName:Abp.Mailing.Smtp.Password": "Heslo",
|
||||
"DisplayName:Abp.Mailing.Smtp.Domain": "Doména",
|
||||
"DisplayName:Abp.Mailing.Smtp.EnableSsl": "Povolit SSL",
|
||||
"DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "Použít výchozí přihlašovací údaje",
|
||||
"Description:Abp.Mailing.DefaultFromAddress": "Výchozí adresa odesílatele",
|
||||
"Description:Abp.Mailing.DefaultFromDisplayName": "Výchozí zobrazované jméno odesilátele",
|
||||
"Description:Abp.Mailing.Smtp.Host": "Název nebo IP adresa hostitele použitého pro SMTP transakce.",
|
||||
"Description:Abp.Mailing.Smtp.Port": "Port použitý pro SMTP tansakce",
|
||||
"Description:Abp.Mailing.Smtp.UserName": "Uživatelské jméno spojené s přihlašovacími údaji.",
|
||||
"Description:Abp.Mailing.Smtp.Password": "Heslo pro uživatelské jméno spojené s přihlašovacími údaji.",
|
||||
"Description:Abp.Mailing.Smtp.Domain": "Název domény nebo počítače, který ověřuje přihlašovací údaje.",
|
||||
"Description:Abp.Mailing.Smtp.EnableSsl": "Zda SmtpClient používá SSL k šifrování připojení.",
|
||||
"Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Zda jsou výchozí přihlašovací údaje odesílány s požadavky."
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"culture": "cs",
|
||||
"texts": {
|
||||
"DisplayName:Abp.Localization.DefaultLanguage": "Výchozí jazyk",
|
||||
"Description:Abp.Localization.DefaultLanguage": "Váchozí jazyk aplikace."
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"DisplayName:Abp.Localization.DefaultLanguage": "預設語系",
|
||||
"Description:Abp.Localization.DefaultLanguage": "應用程式的預設語系."
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Menu:Administration": "管理"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"InternalServerErrorMessage": "對不起,在處理你的請求期間,產生了一個伺服器內部錯誤!",
|
||||
"ValidationErrorMessage": "你的請求無效!",
|
||||
"ValidationNarrativeErrorMessageTitle": "驗證時發現以下錯誤.",
|
||||
"DefaultErrorMessage": "發生錯誤!",
|
||||
"DefaultErrorMessageDetail": "伺服器未發送錯誤的詳細信息.",
|
||||
"DefaultErrorMessage401": "未通過身份驗證!",
|
||||
"DefaultErrorMessage401Detail": "你需要進行身份認證(登入)後再執行此操作.",
|
||||
"DefaultErrorMessage403": "你沒有權限!",
|
||||
"DefaultErrorMessage403Detail": "你不能執行此操作!",
|
||||
"DefaultErrorMessage404": "未找到資源!",
|
||||
"DefaultErrorMessage404Detail": "未在服務中找到請求的資源!",
|
||||
"EntityNotFoundErrorMessage": "實體 {0} 不存在,id = {1}!",
|
||||
"Error": "錯誤",
|
||||
"AreYouSure": "你確定嗎?",
|
||||
"Cancel": "取消",
|
||||
"Yes": "是",
|
||||
"No": "否",
|
||||
"Close": "關閉",
|
||||
"Save": "保存",
|
||||
"SavingWithThreeDot": "保存中...",
|
||||
"Actions": "操作",
|
||||
"Delete": "刪除",
|
||||
"Edit": "修改",
|
||||
"Refresh": "刷新",
|
||||
"ProcessingWithThreeDot": "處理中...",
|
||||
"LoadingWithThreeDot": "載入中...",
|
||||
"Welcome": "歡迎",
|
||||
"Login": "登入",
|
||||
"Register": "註冊",
|
||||
"Logout": "登出",
|
||||
"Submit": "提交",
|
||||
"Back": "返回",
|
||||
"PagerSearch": "搜尋",
|
||||
"PagerNext": "下一頁",
|
||||
"PagerPrevious": "上一頁",
|
||||
"PagerFirst": "首頁",
|
||||
"PagerLast": "末頁",
|
||||
"PagerInfo": "顯示 _TOTAL_ 個紀錄的 _START_ 到 _END_ 個.",
|
||||
"PagerInfoEmpty": "顯示0個紀錄中的0到0",
|
||||
"PagerInfoFiltered": "(從 _MAX_ 所有紀錄中過濾掉)",
|
||||
"NoDataAvailableInDatatable": "資料表中沒有資料",
|
||||
"PagerShowMenuEntries": "顯示 _MENU_ 實體",
|
||||
"DatatableActionDropdownDefaultText": "操作",
|
||||
"ChangePassword": "修改密碼",
|
||||
"PersonalInfo": "個人資料",
|
||||
"AreYouSureYouWantToCancelEditingWarningMessage": "你有未保存的更改.",
|
||||
"UnhandledException": "未處理的異常!",
|
||||
"401Message": "未授權",
|
||||
"403Message": "禁止訪問",
|
||||
"404Message": "網頁未找到",
|
||||
"500Message": "內部伺服器錯誤",
|
||||
"GoHomePage": "返回首頁",
|
||||
"GoBack": "返回"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"'{0}' and '{1}' do not match.": "'{0}'與'{1}'不匹配.",
|
||||
"The {0} field is not a valid credit card number.": "欄位{0}不是有效的信用卡號碼.",
|
||||
"{0} is not valid.": "{0}驗證未通過.",
|
||||
"The {0} field is not a valid e-mail address.": "欄位{0}不是有效的電子郵件地址.",
|
||||
"The {0} field only accepts files with the following extensions: {1}": "{0}欄位只允許以下副檔名的文件: {1}",
|
||||
"The field {0} must be a string or array type with a maximum length of '{1}'.": "欄位{0}必須是最大長度為'{1}'的字串或陣列.",
|
||||
"The field {0} must be a string or array type with a minimum length of '{1}'.": "欄位{0}必須是最小長度為'{1}'的字串或陣列.",
|
||||
"The {0} field is not a valid phone number.": "欄位{0}不是有效的電話號碼.",
|
||||
"The field {0} must be between {1} and {2}.": "欄位{0}值必須在{1}和{2}範圍內.",
|
||||
"The field {0} must match the regular expression '{1}'.": "欄位{0}必須匹配正規表示式'{1}'.",
|
||||
"The {0} field is required.": "欄位{0}不可為空.",
|
||||
"The field {0} must be a string with a maximum length of {1}.": "欄位{0}必須是長度為{1}的字串.",
|
||||
"The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "欄位{0}必須是最小長度為{2}並且最大長度{1}的字串.",
|
||||
"The {0} field is not a valid fully-qualified http, https, or ftp URL.": "欄位{0}不是有效的完全限定的http,https或ftp URL.",
|
||||
"The field {0} is invalid.": "此欄位{0}是無效值.",
|
||||
"ThisFieldIsNotAValidCreditCardNumber.": "此欄位不是有效的信用卡號碼.",
|
||||
"ThisFieldIsNotValid.": "此驗證未通過.",
|
||||
"ThisFieldIsNotAValidEmailAddress.": "此欄位不是有效的郵箱地址.",
|
||||
"ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "此欄位只允許以下副檔名的文件: {0}",
|
||||
"ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthoOf{0}": "此欄位必須是最大長度為'{0}'的字串或陣列.",
|
||||
"ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "此欄位必須是最小長度為'{0}'的字串或陣列.",
|
||||
"ThisFieldIsNotAValidPhoneNumber.": "此欄位不是有效的電話號碼.",
|
||||
"ThisFieldMustBeBetween{0}And{1}": "此欄位值必須在{0}和{1}範圍內.",
|
||||
"ThisFieldMustMatchTheRegularExpression{0}": "此欄位必須匹配正規表示式'{0}'.",
|
||||
"ThisFieldIsRequired.": "此欄位不可為空.",
|
||||
"ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "此欄位必須是長度為{0}的字串.",
|
||||
"ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "此欄位必須是最小長度為{1}並且最大長度{0}的字串.",
|
||||
"ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "此欄位不是有效的完全限定的http,https或ftp URL.",
|
||||
"ThisFieldIsInvalid.": "此欄位是無效值."
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"BirthDate": "生日",
|
||||
"Value1": "值1"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"USA": "美國",
|
||||
"Brazil": "巴西"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"ThisFieldIsRequired": "此欄位為必填欄位",
|
||||
"MaxLenghtErrorMessage": "此欄位最多可包含'{0}'個字元"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Hello <b>{0}</b>.": "您好 <b>{0}</b>.",
|
||||
"Car": "汽車",
|
||||
"CarPlural": "汽車",
|
||||
"MaxLenghtErrorMessage": "此欄位的長度最多'{0}'個字元",
|
||||
"Universe": "宇宙",
|
||||
"FortyTwo": "四十二"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"UserName": "使用者名稱",
|
||||
"EmailAddress": "電子信箱地址",
|
||||
"UserNameOrEmailAddress": "使用者名稱或電子信箱地址",
|
||||
"Password": "密碼",
|
||||
"RememberMe": "記住我",
|
||||
"UseAnotherServiceToLogin": "使用另一個服務登入",
|
||||
"UserLockedOutMessage": "登入失敗,使用者帳號已被鎖定.請稍後再試.",
|
||||
"InvalidUserNameOrPassword": "使用者名稱或密碼錯誤!",
|
||||
"LoginIsNotAllowed": "無法登入!你需要驗證電子信箱地址/手機號碼.",
|
||||
"SelfRegistrationDisabledMessage": "應用程式未開放註冊,請聯絡管理員以加入新使用者.",
|
||||
"Login": "登入",
|
||||
"Cancel": "取消",
|
||||
"Register": "註冊",
|
||||
"AreYouANewUser": "你是新使用者嗎?",
|
||||
"AlreadyRegistered": "已經註冊過了?",
|
||||
"InvalidLoginRequest": "登入請求無效",
|
||||
"ThereAreNoLoginSchemesConfiguredForThisClient": "沒有為此客戶端配置登入方案.",
|
||||
"LogInUsingYourProviderAccount": "使用你的{0}帳號登入",
|
||||
"DisplayName:CurrentPassword": "目前密碼",
|
||||
"DisplayName:NewPassword": "新密碼",
|
||||
"DisplayName:NewPasswordConfirm": "確認新密碼",
|
||||
"PasswordChangedMessage": "你的密碼已修改成功.",
|
||||
"DisplayName:UserName": "使用者名稱",
|
||||
"DisplayName:Email": "電子信箱",
|
||||
"DisplayName:Name": "名字",
|
||||
"DisplayName:Surname": "姓",
|
||||
"DisplayName:Password": "密碼",
|
||||
"DisplayName:EmailAddress": "電子信箱地址",
|
||||
"DisplayName:PhoneNumber": "電話號碼",
|
||||
"PersonalSettings": "個人設置",
|
||||
"PersonalSettingsSaved": "個人設置已保存",
|
||||
"PasswordChanged": "修改密碼",
|
||||
"NewPasswordConfirmFailed": "請確認新密碼",
|
||||
"Manage": "管理",
|
||||
"ManageYourProfile": "管理你的個人資料",
|
||||
"DisplayName:Abp.Account.IsSelfRegistrationEnabled": "啟用自行註冊",
|
||||
"Description:Abp.Account.IsSelfRegistrationEnabled": "是否允許使用者自行註冊帳號.",
|
||||
"DisplayName:Abp.Account.EnableLocalLogin": "使用本地帳號進行身分驗證",
|
||||
"Description:Abp.Account.EnableLocalLogin": "伺服器是否允許使用者使用本地帳號進行身份驗證。"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Permission:Blogging": "部落格",
|
||||
"Permission:Blogs": "部落格",
|
||||
"Permission:Posts": "文章",
|
||||
"Permission:Tags": "標籤",
|
||||
"Permission:Comments": "評論",
|
||||
"Permission:Management": "管理",
|
||||
"Permission:Edit": "標及",
|
||||
"Permission:Create": "新增",
|
||||
"Permission:Delete": "刪除"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Menu:Blogs": "部落格",
|
||||
"Menu:BlogManagement": "部落格管理",
|
||||
"Title": "標題",
|
||||
"Delete": "刪除",
|
||||
"Reply": "回覆",
|
||||
"ReplyTo": "回覆 {0}",
|
||||
"ContinueReading": "繼續閱讀",
|
||||
"DaysAgo": "{0}天前",
|
||||
"YearsAgo": "{0}年前",
|
||||
"MonthsAgo": "{0}個月前",
|
||||
"WeeksAgo": "{0}週前",
|
||||
"MinutesAgo": "{0}分前",
|
||||
"SecondsAgo": "{0}秒前",
|
||||
"HoursAgo": "{0}小時前",
|
||||
"Now": "剛剛",
|
||||
"Content": "內容",
|
||||
"SeeAll": "查看所有",
|
||||
"PopularTags": "熱門標籤",
|
||||
"WiewsWithCount": "{0}人查看",
|
||||
"LastPosts": "最後的文章",
|
||||
"LeaveComment": "發表評論",
|
||||
"TagsInThisArticle": "文章中的標籤",
|
||||
"Posts": "文章",
|
||||
"Edit": "編輯",
|
||||
"BLOG": "部落格",
|
||||
"CommentDeletionWarningMessage": "評論將被刪除.",
|
||||
"PostDeletionWarningMessage": "文章將被刪除.",
|
||||
"BlogDeletionWarningMessage": "部落格將被刪除.",
|
||||
"AreYouSure": "您確定嗎?",
|
||||
"CommentWithCount": "{0}個評論",
|
||||
"Comment": "評論",
|
||||
"ShareOnTwitter": "分享到Twitter",
|
||||
"CoverImage": "封面圖",
|
||||
"CreateANewPost": "新增一篇文章",
|
||||
"CreateANewBlog": "新增一個部落格",
|
||||
"WhatIsNew": "最新消息",
|
||||
"Name": "名稱",
|
||||
"ShortName": "簡稱",
|
||||
"CreationTime": "建立時間",
|
||||
"Description": "描述",
|
||||
"Blogs": "部落格",
|
||||
"Tags": "標籤"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"DocsTitle": "VoloDocs",
|
||||
"WelcomeVoloDocs": "歡迎使用VoloDocs!",
|
||||
"NoProjectWarning": "目前沒有專案!",
|
||||
"CreateYourFirstProject": "建立您的第一個專案",
|
||||
"NoProject": "沒有專案!"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Permission:DocumentManagement": "文件管理",
|
||||
"Permission:Projects": "專案",
|
||||
"Permission:Edit": "編輯",
|
||||
"Permission:Delete": "刪除",
|
||||
"Permission:Create": "建立",
|
||||
"Menu:DocumentManagement": "文件管理",
|
||||
"Menu:ProjectManagement": "專案管理",
|
||||
"CreateANewProject": "建立新專案",
|
||||
"Edit": "編輯",
|
||||
"Create": "建立",
|
||||
"Projects": "專案",
|
||||
"Name": "名稱",
|
||||
"ShortName": "簡稱",
|
||||
"DocumentStoreType": "文件存儲類型",
|
||||
"Format": "格式",
|
||||
"ShortNameInfoText": "將用於唯一的URL.",
|
||||
"DisplayName:Name": "名稱",
|
||||
"DisplayName:ShortName": "簡稱",
|
||||
"DisplayName:Format": "格式",
|
||||
"DisplayName:DefaultDocumentName": "預設文件名稱",
|
||||
"DisplayName:NavigationDocumentName": "導覽文件名稱",
|
||||
"DisplayName:MinimumVersion": "最低版本",
|
||||
"DisplayName:MainWebsiteUrl": "主網站網址",
|
||||
"DisplayName:LatestVersionBranchName": "最新版本的分支名稱",
|
||||
"DisplayName:GitHubRootUrl": "GitHub根網址",
|
||||
"DisplayName:GitHubAccessToken": "GitHub 存取Token ",
|
||||
"DisplayName:GitHubUserAgent": "GitHub 使用者代理"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Documents": "文件",
|
||||
"BackToWebsite": "返回主網站",
|
||||
"Contributors": "貢獻者",
|
||||
"ShareOn": "分享到",
|
||||
"Version": "版本",
|
||||
"Edit": "編輯",
|
||||
"Delete": "刪除",
|
||||
"InThisDocument": "在此文件中",
|
||||
"GoToTop": "到最上方",
|
||||
"Projects": "專案",
|
||||
"NoProjectWarning": "沒有專案!",
|
||||
"DocumentNotFound": "找不到要求的文件!",
|
||||
"NavigationDocumentNotFound": "這個版本沒有導覽文件!",
|
||||
"DocumentNotFoundInSelectedLanguage": "本文件不適用於所選語系,將以預設語系顯示.",
|
||||
"FilterTopics": "過濾主題"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Features": "功能",
|
||||
"NoFeatureFoundMessage": "沒有可用的功能."
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,103 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Menu:IdentityManagement": "身份識別管理",
|
||||
"Users": "使用者",
|
||||
"NewUser": "新使用者",
|
||||
"UserName": "使用者名稱",
|
||||
"EmailAddress": "電子信箱地址",
|
||||
"PhoneNumber": "手機號碼",
|
||||
"UserInformations": "用戶資訊",
|
||||
"DisplayName:IsDefault": "預設",
|
||||
"DisplayName:IsStatic": "靜態",
|
||||
"DisplayName:IsPublic": "公開",
|
||||
"Roles": "角色",
|
||||
"Password": "密碼",
|
||||
"PersonalInfo": " 個人資料",
|
||||
"PersonalSettings": "個人設置",
|
||||
"UserDeletionConfirmationMessage": "使用者 '{0}' 將被刪除. 你確定嗎?",
|
||||
"RoleDeletionConfirmationMessage": "角色 '{0}' 將被刪除. 你確定嗎?",
|
||||
"DisplayName:RoleName": "角色名稱",
|
||||
"DisplayName:UserName": "使用者名稱",
|
||||
"DisplayName:Name": "名子",
|
||||
"DisplayName:Surname": "姓",
|
||||
"DisplayName:Password": "密碼",
|
||||
"DisplayName:Email": "電子信箱地址",
|
||||
"DisplayName:PhoneNumber": "手機號碼",
|
||||
"DisplayName:TwoFactorEnabled": "二次認證",
|
||||
"DisplayName:LockoutEnabled": "登入失敗,帳號被鎖定",
|
||||
"NewRole": "新角色",
|
||||
"RoleName": "角色名稱",
|
||||
"CreationTime": "建立時間",
|
||||
"Permissions": "權限",
|
||||
"DisplayName:CurrentPassword": "目前密碼",
|
||||
"DisplayName:NewPassword": "新密碼",
|
||||
"DisplayName:NewPasswordConfirm": "確認新密碼",
|
||||
"PasswordChangedMessage": "你已成功更改密碼.",
|
||||
"PersonalSettingsSavedMessage": "你的個人設置保存成功.",
|
||||
"Identity.DefaultError": "發生了一個未知錯誤.",
|
||||
"Identity.ConcurrencyFailure": "對象已被修改,因樂觀並行控制導致失敗.",
|
||||
"Identity.DuplicateEmail": "電子信箱 '{0}' 已存在.",
|
||||
"Identity.DuplicateRoleName": "角色名 '{0}' 已存在.",
|
||||
"Identity.DuplicateUserName": "使用者名稱 '{0}' 已存在.",
|
||||
"Identity.InvalidEmail": "電子信箱 '{0}' 無效.",
|
||||
"Identity.InvalidPasswordHasherCompatibilityMode": "提供的 PasswordHasherCompatibilityMode 無效.",
|
||||
"Identity.InvalidPasswordHasherIterationCount": "迭代計數必須是正整數.",
|
||||
"Identity.InvalidRoleName": "角色名 '{0}' 無效.",
|
||||
"Identity.InvalidToken": "token無效.",
|
||||
"Identity.InvalidUserName": "使用者名稱 '{0}' 無效, 只能包含字母或數字.",
|
||||
"Identity.LoginAlreadyAssociated": "此登入名的使用者已存在.",
|
||||
"Identity.PasswordMismatch": "密碼錯誤.",
|
||||
"Identity.PasswordRequiresDigit": "密碼至少包含一位數字 ('0'-'9').",
|
||||
"Identity.PasswordRequiresLower": "密碼至少包含一位小寫字母 ('a'-'z').",
|
||||
"Identity.PasswordRequiresNonAlphanumeric": "密碼至少包含一位非字母數字字元.",
|
||||
"Identity.PasswordRequiresUpper": "密碼至少包含一位大寫字母 ('A'-'Z').",
|
||||
"Identity.PasswordTooShort": "密碼至少為{0}個字元.",
|
||||
"Identity.RoleNotFound": "角色 {0} 不存在.",
|
||||
"Identity.UserAlreadyHasPassword": "使用者已設置密碼.",
|
||||
"Identity.UserAlreadyInRole": "使用者已具有角色 '{0}'.",
|
||||
"Identity.UserLockedOut": "使用者被鎖定.",
|
||||
"Identity.UserLockoutNotEnabled": "該使用者未啟用鎖定.",
|
||||
"Identity.UserNameNotFound": "使用者 {0} 不存在.",
|
||||
"Identity.UserNotInRole": "使用者不具有 '{0}' 角色.",
|
||||
"Identity.PasswordConfirmationFailed": "密碼或確認密碼不一致.",
|
||||
"Identity.StaticRoleRenamingErrorMessage": "無法重命名靜態角色.",
|
||||
"Identity.StaticRoleDeletionErrorMessage": "無法刪除靜態角色.",
|
||||
"Volo.Abp.Identity:010001": "您無法刪除自己的帳號!",
|
||||
"Permission:IdentityManagement": "身份識別管理",
|
||||
"Permission:RoleManagement": "角色管理",
|
||||
"Permission:Create": "建立",
|
||||
"Permission:Edit": "編輯",
|
||||
"Permission:Delete": "刪除",
|
||||
"Permission:ChangePermissions": "更改權限",
|
||||
"Permission:UserManagement": "使用者管理",
|
||||
"Permission:UserLookup": "使用者查詢",
|
||||
"DisplayName:Abp.Identity.Password.RequiredLength": "要求長度",
|
||||
"DisplayName:Abp.Identity.Password.RequiredUniqueChars": "要求唯一字元數量",
|
||||
"DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "要求非字母數字",
|
||||
"DisplayName:Abp.Identity.Password.RequireLowercase": "要求小寫字母",
|
||||
"DisplayName:Abp.Identity.Password.RequireUppercase": "要求大寫字母",
|
||||
"DisplayName:Abp.Identity.Password.RequireDigit": "要求數字",
|
||||
"DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "允許新使用者",
|
||||
"DisplayName:Abp.Identity.Lockout.LockoutDuration": "鎖定時間(秒)",
|
||||
"DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "最大失敗存取嘗試次數",
|
||||
"DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "要求驗證的電子信箱",
|
||||
"DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "要求驗證的手機號碼",
|
||||
"DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "啟用使用者名稱更新",
|
||||
"DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "啟用電子信箱更新",
|
||||
"Description:Abp.Identity.Password.RequiredLength": "密碼的最小長度.",
|
||||
"Description:Abp.Identity.Password.RequiredUniqueChars": "密碼必須包含唯一字元的數量.",
|
||||
"Description:Abp.Identity.Password.RequireNonAlphanumeric": "密碼是否必須包含非字母數字.",
|
||||
"Description:Abp.Identity.Password.RequireLowercase": "密碼是否必須包含小寫字母.",
|
||||
"Description:Abp.Identity.Password.RequireUppercase": "密碼是否必須包含大小字母.",
|
||||
"Description:Abp.Identity.Password.RequireDigit": "密碼是否必須包含數字.",
|
||||
"Description:Abp.Identity.Lockout.AllowedForNewUsers": "允許新使用者被鎖定.",
|
||||
"Description:Abp.Identity.Lockout.LockoutDuration": "當鎖定發生時使用者被鎖定的時間(秒).",
|
||||
"Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "如果啟用鎖定,當使用者被鎖定前失敗的存取嘗試次數.",
|
||||
"Description:Abp.Identity.SignIn.RequireConfirmedEmail": "登入時是否需要驗證電子信箱.",
|
||||
"Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "登入時是否需要驗證手機號碼.",
|
||||
"Description:Abp.Identity.User.IsUserNameUpdateEnabled": "是否允許使用者更新使用者名稱.",
|
||||
"Description:Abp.Identity.User.IsEmailUpdateEnabled": "是否允許使用者更新電子信箱."
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Volo.IdentityServer:DuplicateIdentityResourceName": "Identity資源名稱已存在: {Name}",
|
||||
"Volo.IdentityServer:DuplicateApiResourceName": "Api資源名稱已存在: {Name}",
|
||||
"Volo.IdentityServer:DuplicateClientId": "ClientId已經存在: {ClientId}"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Permissions": "權限",
|
||||
"OnlyProviderPermissons": "只有這個提供者",
|
||||
"All": "全部",
|
||||
"SelectAllInAllTabs": "授予所有權限",
|
||||
"SelectAllInThisTab": "全選"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Settings": "設置",
|
||||
"SuccessfullySaved": "保存成功"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"culture": "zh-Hant",
|
||||
"texts": {
|
||||
"Menu:TenantManagement": "租戶管理",
|
||||
"Tenants": "租戶",
|
||||
"NewTenant": "新租戶",
|
||||
"TenantName": "租戶名稱",
|
||||
"DisplayName:TenantName": "租戶名稱",
|
||||
"TenantDeletionConfirmationMessage": "租戶 '{0}' 將被刪除. 您確定嗎?",
|
||||
"ConnectionStrings": "資料庫連線字串",
|
||||
"DisplayName:DefaultConnectionString": "預設資料庫連線字串",
|
||||
"DisplayName:UseSharedDatabase": "使用共用資料庫",
|
||||
"Permission:TenantManagement": "租戶管理",
|
||||
"Permission:Create": "新增",
|
||||
"Permission:Edit": "編輯",
|
||||
"Permission:Delete": "刪除",
|
||||
"Permission:ManageConnectionStrings": "管理資料庫連線字串",
|
||||
"Permission:ManageFeatures": "管理功能"
|
||||
}
|
||||
}
|
||||