- @if (Model.Posts.Count > 3)
+ @if (Model.Posts.Count > 4)
{
@L["LastPosts"]
- @for (var index = 3; index < Model.Posts.Count; index++)
+ @for (var index = 4; index < Model.Posts.Count; index++)
{
var post = Model.Posts[index];
- var oddPost = index % 2 == 1;
+ var oddPost = index % 2 == 0;
From a21fb0602c20c751a1e486fddda4e77ca26055ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?=
Date: Fri, 12 Jun 2020 14:58:13 +0300
Subject: [PATCH 68/81] Rename Clock to Timing.
---
docs/en/AspNet-Boilerplate-Migration-Guide.md | 2 +-
docs/en/Clock.md | 3 ---
docs/en/Timing.md | 3 +++
docs/en/docs-nav.json | 4 ++++
4 files changed, 8 insertions(+), 4 deletions(-)
delete mode 100644 docs/en/Clock.md
create mode 100644 docs/en/Timing.md
diff --git a/docs/en/AspNet-Boilerplate-Migration-Guide.md b/docs/en/AspNet-Boilerplate-Migration-Guide.md
index 39dd01eaa4..9929b6d24d 100644
--- a/docs/en/AspNet-Boilerplate-Migration-Guide.md
+++ b/docs/en/AspNet-Boilerplate-Migration-Guide.md
@@ -595,7 +595,7 @@ ABP Framework separates it and provides the setting management module (pre-added
ASP.NET Boilerplate has a static `Clock` service ([see](https://aspnetboilerplate.com/Pages/Documents/Timing)) which is used to abstract the `DateTime` kind, so you can easily switch between Local and UTC times. You don't inject it, but just use the `Clock.Now` static method to obtain the current time.
-ABP Framework has the `IClock` service ([see](Clock.md)) which has a similar goal, but now you need to inject it whenever you need it.
+ABP Framework has the `IClock` service ([see](Timing.md)) which has a similar goal, but now you need to inject it whenever you need it.
### Event Bus
diff --git a/docs/en/Clock.md b/docs/en/Clock.md
deleted file mode 100644
index 46ef1235e0..0000000000
--- a/docs/en/Clock.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Clock
-
-TODO
\ No newline at end of file
diff --git a/docs/en/Timing.md b/docs/en/Timing.md
new file mode 100644
index 0000000000..0fe80ee99b
--- /dev/null
+++ b/docs/en/Timing.md
@@ -0,0 +1,3 @@
+# Timing
+
+TODO
\ No newline at end of file
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index d384902edf..6efda6af9d 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -216,6 +216,10 @@
{
"text": "GUID Generation",
"path": "Guid-Generation.md"
+ },
+ {
+ "text": "Timing",
+ "path": "Timing.md"
}
]
},
From 994a0fa777c07105bb53ea9c25011538c521e152 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?=
Date: Fri, 12 Jun 2020 16:18:53 +0300
Subject: [PATCH 69/81] Complete IClock part of the Timing document.
---
docs/en/Json.md | 3 ++
docs/en/Timing.md | 98 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 100 insertions(+), 1 deletion(-)
create mode 100644 docs/en/Json.md
diff --git a/docs/en/Json.md b/docs/en/Json.md
new file mode 100644
index 0000000000..f0082ea9d6
--- /dev/null
+++ b/docs/en/Json.md
@@ -0,0 +1,3 @@
+# JSON
+
+TODO
\ No newline at end of file
diff --git a/docs/en/Timing.md b/docs/en/Timing.md
index 0fe80ee99b..f67bd5d180 100644
--- a/docs/en/Timing.md
+++ b/docs/en/Timing.md
@@ -1,3 +1,99 @@
# Timing
-TODO
\ No newline at end of file
+Working with times & [time zones](https://en.wikipedia.org/wiki/Time_zone) is always tricky, especially if you need to build a **global system** that is used by users in **different time zones**.
+
+ABP provides a basic infrastructure to make it easy and handle automatically wherever possible. This document covers the ABP Framework services and systems related to time and time zones.
+
+> If you are creating a local application that runs in a single time zone region, you may not need all these systems. But even in this case, it is suggested to use the `IClock` service introduced in this document.
+
+## IClock
+
+`DateTime.Now` returns a `DateTime` object with the **local date & time of the server**. A `DateTime` object **doesn't store the time zone information**. So, you can not know the **absolute date & time** stored in this object. You can only make **assumptions**, like assuming that it was created in UTC+05 time zone. The things especially gets complicated when you save this value to a database and read later, or send it to a client in a **different time zone**.
+
+One solution to this problem is always use `DateTime.UtcNow` and assume all `DateTime` objects as UTC time. In this was, you can convert it to the time zone of the target client when needed.
+
+`IClock` provides an abstraction while getting the current time, so you can control the kind of the date time (UTC or local) in a single point in your application.
+
+**Example: Getting the current time**
+
+````csharp
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Timing;
+
+namespace AbpDemo
+{
+ public class MyService : ITransientDependency
+ {
+ private readonly IClock _clock;
+
+ public MyService(IClock clock)
+ {
+ _clock = clock;
+ }
+
+ public void Foo()
+ {
+ //Get the current time!
+ var now = _clock.Now;
+ }
+ }
+}
+````
+
+* Inject the `IClock` service when you need to get the current time. Common base classes (like ApplicationService) already injects it and provides as a base property - so, you can directly use as `Clock`.
+* Use the `Now` property to get the current time.
+
+> Most of the times, `IClock` is the only service you need to know and use in your application.
+
+### Clock Options
+
+`AbpClockOptions` is the [options](Options.md) class that used to set the clock kind.
+
+**Example: Use UTC Clock**
+
+````csharp
+Configure(options =>
+{
+ options.Kind = DateTimeKind.Utc;
+});
+````
+
+Write this inside the `ConfigureServices` method of your [module](Module-Development-Basics.md).
+
+> Default `Kind` is `Unspecified`, that actually make the Clock as it doesn't exists at all. Either make it `Utc` or `Local` if you want to get benefit of the Clock system.
+
+### DateTime Normalization
+
+Other important function of the `IClock` is to normalize `DateTime` objects.
+
+**Example usage:**
+
+````csharp
+DateTime dateTime = ...; //Get from somewhere
+var normalizedDateTime = Clock.Normalize(dateTime)
+````
+
+`Normalize` method works as described below:
+
+* Converts the given `DateTime` to the UTC (by using the `DateTime.ToUniversalTime()` method) if current Clock is UTC and given `DateTime` is local.
+* Converts the given `DateTime` to the local (by using the `DateTime.ToLocalTime()` method) if current Clock is local and given `DateTime` is UTC.
+* Sets `Kind` of the given `DateTime` (using the `DateTime.SpecifyKind(...)` method) to the `Kind` of the current Clock if given `DateTime`'s `Kind` is `Unspecified`.
+
+`Normalize` method is used by the ABP Framework when the it gets a `DateTime` that is not created by `IClock.Now` and may not be compatible with the current Clock type. Examples;
+
+* `DateTime` type binding in the ASP.NET Core MVC model binding.
+* Saving data to and reading data from database via [Entity Framework Core](Entity-Framework-Core.md).
+* Working with `DateTime` objects on [JSON deserialization](Json.md).
+
+#### DisableDateTimeNormalization Attribute
+
+`DisableDateTimeNormalization` attribute can be used to disable the normalization operation for desired classes or properties.
+
+### Other IClock Properties
+
+In addition to the `Now`, `IClock` service has the following properties:
+
+* `Kind`: Returns a `DateTimeKind` for the currently used clock type (`DateTimeKind.Utc`, `DateTimeKind.Local` or `DateTimeKind.Unspecified`).
+* `SupportsMultipleTimezone`: Returns `true` if currently used clock is UTC.
+
+###
\ No newline at end of file
From 75b255f10f540c15ba8ccddc164d43697d353255 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?=
Date: Fri, 12 Jun 2020 18:25:29 +0300
Subject: [PATCH 70/81] Don't set null for the timing config.
---
.../AbpApplicationConfigurationAppService.cs | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs
index f68d4d1450..6ad5b3276e 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs
@@ -188,7 +188,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
ThreeLetterIsoLanguageName = CultureInfo.CurrentUICulture.ThreeLetterISOLanguageName,
DateTimeFormat = new DateTimeFormatDto
{
- CalendarAlgorithmType = CultureInfo.CurrentUICulture.DateTimeFormat.Calendar.AlgorithmType.ToString(),
+ CalendarAlgorithmType =
+ CultureInfo.CurrentUICulture.DateTimeFormat.Calendar.AlgorithmType.ToString(),
DateTimeFormatLong = CultureInfo.CurrentUICulture.DateTimeFormat.LongDatePattern,
ShortDatePattern = CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern,
FullDateTimePattern = CultureInfo.CurrentUICulture.DateTimeFormat.FullDateTimePattern,
@@ -238,25 +239,24 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
protected virtual async Task GetTimingConfigAsync()
{
- var result = new TimingDto();
-
var windowsTimeZoneId = await _settingProvider.GetOrNullAsync(TimingSettingNames.TimeZone);
- if (!windowsTimeZoneId.IsNullOrWhiteSpace())
+
+ return new TimingDto
{
- result.TimeZone = new TimeZone
+ TimeZone = new TimeZone
{
Windows = new WindowsTimeZone
{
TimeZoneId = windowsTimeZoneId
},
- Iana = new IanaTimeZone()
+ Iana = new IanaTimeZone
{
- TimeZoneName = _timezoneProvider.WindowsToIana(windowsTimeZoneId)
+ TimeZoneName = windowsTimeZoneId.IsNullOrWhiteSpace()
+ ? null
+ : _timezoneProvider.WindowsToIana(windowsTimeZoneId)
}
- };
- }
-
- return result;
+ }
+ };
}
protected virtual ClockDto GetClockConfig()
@@ -267,4 +267,4 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
};
}
}
-}
+}
\ No newline at end of file
From 4003b64ca10d05c29fa8c084761225fa333f350c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?=
Date: Fri, 12 Jun 2020 19:06:53 +0300
Subject: [PATCH 71/81] Added Application Configuration Endpoint document
---
docs/en/API/Application-Configuration.md | 23 +++++++++++++++++++++++
docs/en/docs-nav.json | 9 +++++++++
2 files changed, 32 insertions(+)
create mode 100644 docs/en/API/Application-Configuration.md
diff --git a/docs/en/API/Application-Configuration.md b/docs/en/API/Application-Configuration.md
new file mode 100644
index 0000000000..db624987c5
--- /dev/null
+++ b/docs/en/API/Application-Configuration.md
@@ -0,0 +1,23 @@
+# Application Configuration Endpoint
+
+ABP Framework provides a pre-built and standard endpoint that contains some useful information about the application/service. Here, the list of some fundamental information at this endpoint:
+
+* [Localization](Localization.md) values, supported and the current language of the application.
+* Available and granted [policies](Authorization.md) (permissions) for the current user.
+* [Setting](Settings.md) values for the current user.
+* Info about the [current user](CurrentUser.md) (like id and user name).
+* Info about the current [tenant](Multi-Tenancy.md) (like id and name).
+* [Time zone](Timing.md) information for the current user and the [clock](Timing.md) type of the application.
+
+## HTTP API
+
+If you navigate to the `/api/abp/application-configuration` URL of an ABP Framework based web application or HTTP Service, you can access the configuration as a JSON object. This endpoint is useful to create the client of your application.
+
+## Script
+
+For ASP.NET Core MVC (Razor Pages) applications, the same configuration values are also available on the JavaScript side. `/Abp/ApplicationConfigurationScript` is the URL of the script that is auto-generated based on the HTTP API above.
+
+See the [JavaScript API document](../UI/AspNetCore/JavaScript-API/Index.md) for the ASP.NET Core UI.
+
+Other UI types provide services native to the related platform. For example, see the [Angular UI localization documentation](../UI/Angular/Localization.md) to learn how to use the localization values exposes by this endpoint.
+
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index 6efda6af9d..15abdb22ff 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -300,6 +300,15 @@
{
"text": "Dynamic C# API Clients",
"path": "API/Dynamic-CSharp-API-Clients.md"
+ },
+ {
+ "text": "ABP Endpoints",
+ "items": [
+ {
+ "text": "Application Configuration",
+ "path": "API/Application-Configuration.md"
+ }
+ ]
}
]
},
From 87078bbd2792cf535325c20817ea33a8fcdbbf22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?=
Date: Fri, 12 Jun 2020 19:07:47 +0300
Subject: [PATCH 72/81] Move JavaScript-API document and enhance timing doc.
---
docs/en/API/JavaScript-API/Auth.md | 3 ---
docs/en/AspNetCore/JavaScript-API/Auth.md | 3 ---
docs/en/AspNetCore/JavaScript-API/Index.md | 3 ---
docs/en/Timing.md | 16 +++++++++++++++-
.../AspNetCore}/JavaScript-API/Index.md | 5 ++---
5 files changed, 17 insertions(+), 13 deletions(-)
delete mode 100644 docs/en/API/JavaScript-API/Auth.md
delete mode 100644 docs/en/AspNetCore/JavaScript-API/Auth.md
delete mode 100644 docs/en/AspNetCore/JavaScript-API/Index.md
rename docs/en/{API => UI/AspNetCore}/JavaScript-API/Index.md (92%)
diff --git a/docs/en/API/JavaScript-API/Auth.md b/docs/en/API/JavaScript-API/Auth.md
deleted file mode 100644
index 60c9eb8866..0000000000
--- a/docs/en/API/JavaScript-API/Auth.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# abp.auth JavaScript API
-
-TODO
\ No newline at end of file
diff --git a/docs/en/AspNetCore/JavaScript-API/Auth.md b/docs/en/AspNetCore/JavaScript-API/Auth.md
deleted file mode 100644
index fb83bcfbff..0000000000
--- a/docs/en/AspNetCore/JavaScript-API/Auth.md
+++ /dev/null
@@ -1,3 +0,0 @@
-This document has moved.
-
-[Click to navigate to JavaScript Auth document](../../API/JavaScript-API/Auth.md)
\ No newline at end of file
diff --git a/docs/en/AspNetCore/JavaScript-API/Index.md b/docs/en/AspNetCore/JavaScript-API/Index.md
deleted file mode 100644
index 1ed7f0285c..0000000000
--- a/docs/en/AspNetCore/JavaScript-API/Index.md
+++ /dev/null
@@ -1,3 +0,0 @@
-This document has moved.
-
-[Click to navigate to JavaScript API document](../../API/JavaScript-API/Index.md)
\ No newline at end of file
diff --git a/docs/en/Timing.md b/docs/en/Timing.md
index f67bd5d180..fbdd899f22 100644
--- a/docs/en/Timing.md
+++ b/docs/en/Timing.md
@@ -96,4 +96,18 @@ In addition to the `Now`, `IClock` service has the following properties:
* `Kind`: Returns a `DateTimeKind` for the currently used clock type (`DateTimeKind.Utc`, `DateTimeKind.Local` or `DateTimeKind.Unspecified`).
* `SupportsMultipleTimezone`: Returns `true` if currently used clock is UTC.
-###
\ No newline at end of file
+## Time Zones
+
+This section covers the ABP Framework infrastructure related to managing time zones.
+
+### TimeZone Setting
+
+ABP Framework defines a setting, named `Abp.Timing.Timezone`, that can be used to set and get the time zone for a user, [tenant](Multi-Tenancy.md) or globally for the application. The default value is `UTC`.
+
+See the [setting documentation](Settings.md) to learn more about the setting system.
+
+### ITimezoneProvider
+
+`ITimezoneProvider` is a service to simple convert [Windows Time Zone Id](https://support.microsoft.com/en-us/help/973627/microsoft-time-zone-index-values) values to [Iana Time Zone Name](https://www.iana.org/time-zones) values and vice verse. It also provides methods to get list of these time zones and get a `TimeZoneInfo` with a given name.
+
+It has been implemented using the [TimeZoneConverter](https://github.com/mj1856/TimeZoneConverter) library.
\ No newline at end of file
diff --git a/docs/en/API/JavaScript-API/Index.md b/docs/en/UI/AspNetCore/JavaScript-API/Index.md
similarity index 92%
rename from docs/en/API/JavaScript-API/Index.md
rename to docs/en/UI/AspNetCore/JavaScript-API/Index.md
index ca9afca97f..9f584eacfb 100644
--- a/docs/en/API/JavaScript-API/Index.md
+++ b/docs/en/UI/AspNetCore/JavaScript-API/Index.md
@@ -5,7 +5,7 @@ ABP provides some JavaScript APIs for ASP.NET Core MVC / Razor Pages application
## APIs
* abp.ajax
-* [abp.auth](Auth.md)
+* abp.auth
* abp.currentUser
* abp.dom
* abp.event
@@ -20,5 +20,4 @@ ABP provides some JavaScript APIs for ASP.NET Core MVC / Razor Pages application
* abp.utils
* abp.ResourceLoader
* abp.WidgetManager
-* Other APIs
-
+* Other APIs
\ No newline at end of file
From 9f0e2bd0514f7278793846fb7c99af13d43151b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?=
Date: Fri, 12 Jun 2020 22:32:24 +0300
Subject: [PATCH 73/81] Update Timing.md
---
docs/en/Timing.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/Timing.md b/docs/en/Timing.md
index fbdd899f22..4d48fa6d51 100644
--- a/docs/en/Timing.md
+++ b/docs/en/Timing.md
@@ -102,7 +102,7 @@ This section covers the ABP Framework infrastructure related to managing time zo
### TimeZone Setting
-ABP Framework defines a setting, named `Abp.Timing.Timezone`, that can be used to set and get the time zone for a user, [tenant](Multi-Tenancy.md) or globally for the application. The default value is `UTC`.
+ABP Framework defines **a setting**, named `Abp.Timing.Timezone`, that can be used to set and get the time zone for a user, [tenant](Multi-Tenancy.md) or globally for the application. The default value is `UTC`.
See the [setting documentation](Settings.md) to learn more about the setting system.
From ca47f5ad0c60d400f9938139de257b53b92fe003 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?=
Date: Sat, 13 Jun 2020 00:55:12 +0300
Subject: [PATCH 74/81] Complete the Data Transfer Objects document.
---
docs/en/Application-Services.md | 4 +-
docs/en/Data-Transfer-Objects.md | 281 ++++++++++++++++++++++++++++++-
docs/en/Domain-Driven-Design.md | 4 +-
docs/en/docs-nav.json | 3 +-
4 files changed, 285 insertions(+), 7 deletions(-)
diff --git a/docs/en/Application-Services.md b/docs/en/Application-Services.md
index f7f7675f46..d28a7290fb 100644
--- a/docs/en/Application-Services.md
+++ b/docs/en/Application-Services.md
@@ -2,7 +2,7 @@
Application services are used to implement the **use cases** of an application. They are used to **expose domain logic to the presentation layer**.
-An Application Service is called from the presentation layer (optionally) with a **DTO (Data Transfer Object)** as the parameter. It uses domain objects to **perform some specific business logic** and (optionally) returns a DTO back to the presentation layer. Thus, the presentation layer is completely **isolated** from domain layer.
+An Application Service is called from the presentation layer (optionally) with a **DTO ([Data Transfer Object](Data-Transfer-Objects.md))** as the parameter. It uses domain objects to **perform some specific business logic** and (optionally) returns a DTO back to the presentation layer. Thus, the presentation layer is completely **isolated** from domain layer.
## Example
@@ -205,7 +205,7 @@ See the [object to object mapping document](Object-To-Object-Mapping.md) for mor
## Validation
-Inputs of application service methods are automatically validated (like ASP.NET Core controller actions). You can use the standard data annotation attributes or custom validation method to perform the validation. ABP also ensures that the input is not null.
+Inputs of application service methods are automatically validated (like ASP.NET Core controller actions). You can use the standard data annotation attributes or a custom validation method to perform the validation. ABP also ensures that the input is not null.
See the [validation document](Validation.md) for more.
diff --git a/docs/en/Data-Transfer-Objects.md b/docs/en/Data-Transfer-Objects.md
index b0d80246f7..bc81205b66 100644
--- a/docs/en/Data-Transfer-Objects.md
+++ b/docs/en/Data-Transfer-Objects.md
@@ -1,3 +1,280 @@
-## Data Transfer Objects
+# Data Transfer Objects
-TODO
\ No newline at end of file
+## Introduction
+
+**Data Transfer Objects** (DTO) are used to transfer data between the **Application Layer** and the **Presentation Layer** or other type of clients.
+
+Typically, an [application service](Application-Services.md) is called from the presentation layer (optionally) with a **DTO** as the parameter. It uses domain objects to **perform some specific business logic** and (optionally) returns a DTO back to the presentation layer. Thus, the presentation layer is completely **isolated** from domain layer.
+
+### The Need for DTOs
+
+> **You can skip this section** if you feel that you know and confirm the benefits of using DTOs.
+
+At first, creating a DTO class for each application service method can be seen as tedious and time-consuming work. However, they can save your application if you correctly use them. Why & how?
+
+#### Abstraction of the Domain Layer
+
+DTOs provide an efficient way of **abstracting domain objects** from the presentation layer. In effect, your **layers** are correctly separated. If you want to change the presentation layer completely, you can continue with the existing application and domain layers. Alternatively, you can re-write your domain layer, completely change the database schema, entities and O/RM framework, all without changing the presentation layer. This, of course, is as long as the contracts (method signatures and DTOs) of your application services remain unchanged.
+
+#### Data Hiding
+
+Say you have a `User` entity with the properties Id, Name, EmailAddress and Password. If a `GetAllUsers()` method of a `UserAppService` returns a `List`, anyone can access the passwords of all your users, even if you do not show it on the screen. It's not just about security, it's about data hiding. Application services should return only what it needs by the presentation layer (or client). Not more, not less.
+
+#### Serialization & Lazy Load Problems
+
+When you return data (an object) to the presentation layer, it's most likely serialized. For example, in a REST API that returns JSON, your object will be serialized to JSON and sent to the client. Returning an Entity to the presentation layer can be problematic in that regard, especially if you are using a relational database and an ORM provider like Entity Framework Core. How?
+
+In a real-world application, your entities may have references to each other. The `User` entity can have a reference to it's `Role`s. If you want to serialize `User`, its `Role`s are also serialized. The `Role` class may have a `List` and the `Permission` class can has a reference to a `PermissionGroup` class and so on... Imagine all of these objects being serialized at once. You could easily and accidentally serialize your whole database! Also, if your objects have circular references, they may **not** be serialized at all.
+
+What's the solution? Marking properties as `NonSerialized`? No, you can not know when it should be serialized and when it shouldn't be. It may be needed in one application service method, and not needed in another. Returning safe, serializable, and specially designed DTOs is a good choice in this situation.
+
+Almost all O/RM frameworks support lazy-loading. It's a feature that loads entities from the database when they're needed. Say a `User` class has a reference to a `Role` class. When you get a `User` from the database, the `Role` property (or collection) is not filled. When you first read the `Role` property, it's loaded from the database. So, if you return such an Entity to the presentation layer, it will cause it to retrieve additional entities from the database by executing additional queries. If a serialization tool reads the entity, it reads all properties recursively and again your whole database can be retrieved (if there are relations between entities).
+
+More problems can arise if you use Entities in the presentation layer. **It's best not to reference the domain/business layer assembly in the presentation layer.**
+
+If you are convinced about using DTOs, we can continue to what ABP Framework provides and suggests about DTOs.
+
+> ABP doesn't force you to use DTOs, however using DTOs is **strongly suggested as a best practice**.
+
+## Standard Interfaces & Base Classes
+
+A DTO is a simple class that has no dependency and you can design it in any way. However, ABP introduces some **interfaces** to determine the **conventions** for naming **standard properties** and **base classes** to **don't repeat yourself** while declaring **common properties**.
+
+**None of them are required**, but using them **simplifies and standardizes** your application code.
+
+### Entity Related DTOs
+
+You typically create DTOs corresponding to your entities, which results similar classes to your entities. ABP Framework provides some base classes to simplify while creating such DTOs.
+
+#### EntityDto
+
+`IEntityDto` is a simple interface that only defines an `Id` property. You can implement it or inherit from the `EntityDto` for your DTOs that matches to an [entity](Entities.md).
+
+**Example:**
+
+````csharp
+using System;
+using Volo.Abp.Application.Dtos;
+
+namespace AbpDemo
+{
+ public class ProductDto : EntityDto
+ {
+ public string Name { get; set; }
+ //...
+ }
+}
+````
+
+#### Audited DTOs
+
+If your entity inherits from audited entity classes (or implements auditing interfaces), you can use the following base classes to create your DTOs:
+
+* `CreationAuditedEntityDto`
+* `CreationAuditedEntityWithUserDto`
+* `AuditedEntityDto`
+* `AuditedEntityWithUserDto`
+* `FullAuditedEntityDto`
+* `FullAuditedEntityWithUserDto`
+
+#### Extensible DTOs
+
+If you want to use the [object extension system](Object-Extensions.md) for your DTOs, you can use or inherit from the following DTO classes:
+
+* `ExtensibleObject` implements the `IHasExtraProperties` (other classes inherits this class).
+* `ExtensibleEntityDto`
+* `ExtensibleCreationAuditedEntityDto`
+* `ExtensibleCreationAuditedEntityWithUserDto`
+* `ExtensibleAuditedEntityDto`
+* `ExtensibleAuditedEntityWithUserDto`
+* `ExtensibleFullAuditedEntityDto`
+* `ExtensibleFullAuditedEntityWithUserDto`
+
+### List Results
+
+It is common to return a list of DTOs to the client. `IListResult` interface and `ListResultDto` class is used to make it standard.
+
+The definition of the `IListResult` interface:
+
+````csharp
+public interface IListResult
+{
+ IReadOnlyList Items { get; set; }
+}
+````
+
+**Example: Return a list of products**
+
+````csharp
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Domain.Repositories;
+
+namespace AbpDemo
+{
+ public class ProductAppService : ApplicationService, IProductAppService
+ {
+ private readonly IRepository _productRepository;
+
+ public ProductAppService(IRepository productRepository)
+ {
+ _productRepository = productRepository;
+ }
+
+ public async Task> GetListAsync()
+ {
+ //Get entities from the repository
+ List products = await _productRepository.GetListAsync();
+
+ //Map entities to DTOs
+ List productDtos =
+ ObjectMapper.Map, List>(products);
+
+ //Return the result
+ return new ListResultDto(productDtos);
+ }
+ }
+}
+````
+
+You could simply return the `productDtos` object (and change the method return type) and it has nothing wrong. Returning a `ListResultDto` makes your `List` wrapped into another object as an `Items` property. This has one advantage: You can later add more properties to your return value without breaking your remote clients (when they get the value as a JSON result). So, it is especially suggested when you are developing reusable application modules.
+
+### Paged & Sorted List Results
+
+It is more common to request a paged list from server and return a paged list to the client. ABP defines a few interface and classes to standardize it:
+
+#### Input (Request) Types
+
+The following interfaces and classes is to standardize the input sent by the clients.
+
+* `ILimitedResultRequest`: Defines a `MaxResultCount` (`int`) property to request a limited result from the server.
+* `IPagedResultRequest`: Inherits from the `ILimitedResultRequest` (so it inherently has the `MaxResultCount` property) and defines a `SkipCount` (`int`) to declare the skip count while requesting a paged result from the server.
+* `ISortedResultRequest`: Defines a `Sorting` (`string`) property to request a sorted result from the server. Sorting value can be "*Name*", "*Name DESC*", "*Name ASC, Age DESC*"... etc.
+* `IPagedAndSortedResultRequest` inherits from both of the `IPagedResultRequest` and `ISortedResultRequest`, so has `MaxResultCount`, `SkipCount` and `Sorting` properties.
+
+Instead of implementing the interfaces manually, it is suggested to inherit one of the following base DTO classes:
+
+* `LimitedResultRequestDto` implements `ILimitedResultRequest`.
+* `PagedResultRequestDto` implements `IPagedResultRequest` (and inherits from the `LimitedResultRequestDto`).
+* `PagedAndSortedResultRequestDto` implements `IPagedAndSortedResultRequest` (and inherit from the `PagedResultRequestDto`).
+
+##### Max Result Count
+
+`LimitedResultRequestDto` (and inherently the others) limits and validates the `MaxResultCount` by the following rules;
+
+* If the client doesn't set `MaxResultCount`, it is assumed as **10** (the default page size). This value can be changed by setting the `LimitedResultRequestDto.DefaultMaxResultCount` static property.
+* If the client sends `MaxResultCount` greater than **1,000**, it produces a **validation error**. It is important to protect the server from abuse of the service. If you want, you can change this value by setting the `LimitedResultRequestDto.MaxMaxResultCount` static property.
+
+Static properties suggested to be set on application startup since they are static (global).
+
+#### Output (Response) Types
+
+The following interfaces and classes is to standardize the output sent to the clients.
+
+* `IHasTotalCount` defines a `TotalCount` (`long`) property to return the total count of the records in case of paging.
+* `IPagedResult` inherits from the `IListResult` and `IHasTotalCount`, so it has the `Items` and `TotalCount` properties.
+
+Instead of implementing the interfaces manually, it is suggested to inherit one of the following base DTO classes:
+
+* `PagedResultDto` inherits from the `ListResultDto