# Conflicts: # framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csprojpull/5973/head
@ -1,3 +1,2 @@
|
||||
## Basic Theme
|
||||
This document has been moved to [here](../UI/AspNetCore/Basic-Theme.md).
|
||||
|
||||
TODO
|
@ -1,3 +1,90 @@
|
||||
# ASP.NET Core MVC / Razor Pages: The Basic Theme
|
||||
|
||||
This document is in progress. See the [Theming](Theming.md) document.
|
||||
The Basic Theme is a theme implementation for the ASP.NET Core MVC / Razor Pages UI. It is a minimalist theme that doesn't add any styling on top of the plain [Bootstrap](https://getbootstrap.com/). You can take the Basic Theme as the **base theme** and build your own theme or styling on top of it. See the *Customization* section.
|
||||
|
||||
The Basic Theme has RTL (Right-to-Left language) support.
|
||||
|
||||
> If you are looking for a professional, enterprise ready theme, you can check the [Lepton Theme](https://commercial.abp.io/themes), which is a part of the [ABP Commercial](https://commercial.abp.io/).
|
||||
|
||||
> See the [Theming document](Theming.md) to learn about themes.
|
||||
|
||||
## Installation
|
||||
|
||||
**This theme is already installed** when you create a new solution using the [startup templates](../../Startup-Templates/Index.md). If you need to manually install it, follow the steps below:
|
||||
|
||||
* Install the [Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic) NuGet package to your web project.
|
||||
* Add `AbpAspNetCoreMvcUiBasicThemeModule` into the `[DependsOn(...)]` attribute for your [module class](../../Module-Development-Basics.md) in the web project.
|
||||
* Install the [@abp/aspnetcore.mvc.ui.theme.basic](https://www.npmjs.com/package/@abp/aspnetcore.mvc.ui.theme.basic) NPM package to your web project (e.g. `npm install @abp/aspnetcore.mvc.ui.theme.basic` or `yarn add @abp/aspnetcore.mvc.ui.theme.basic`).
|
||||
* Run `gulp` command in a command line terminal in the web project's folder.
|
||||
|
||||
## Layouts
|
||||
|
||||
The Basic Theme implements the standard layouts. All the layouts implement the following parts;
|
||||
|
||||
* Global [Bundles](Bundling-Minification.md)
|
||||
* [Page Alerts](Page-Alerts.md)
|
||||
* [Layout Hooks](Layout-Hooks.md)
|
||||
* [Widget](Widgets.md) Resources
|
||||
|
||||
### The Application Layout
|
||||
|
||||

|
||||
|
||||
Application Layout implements the following parts, in addition to the common parts mentioned above;
|
||||
|
||||
* Branding
|
||||
* Main [Menu](Navigation-Menu.md)
|
||||
* Main [Toolbar](Toolbars.md) with Language Selection & User Menu
|
||||
|
||||
### The Account Layout
|
||||
|
||||

|
||||
|
||||
Application Layout implements the following parts, in addition to the common parts mentioned above;
|
||||
|
||||
* Branding
|
||||
* Main [Menu](Navigation-Menu.md)
|
||||
* Main [Toolbar](Toolbars.md) with Language Selection & User Menu
|
||||
* Tenant Switch Area
|
||||
|
||||
### Empty Layout
|
||||
|
||||
Empty layout is empty, as its name stands for. However, it implements the common parts mentioned above.
|
||||
|
||||
## Customization
|
||||
|
||||
You have two options two customize this theme:
|
||||
|
||||
### Overriding Styles/Components
|
||||
|
||||
In this approach, you continue to use the the theme as NuGet and NPM packages and customize the parts you need to. There are several ways to customize it;
|
||||
|
||||
#### Override the Styles
|
||||
|
||||
1. Create a CSS file in the `wwwroot` folder of your project:
|
||||
|
||||

|
||||
|
||||
2. Add the style file to the global bundle, in the `ConfigureServices` method of your [module](../../Module-Development-Basics.md):
|
||||
|
||||
````csharp
|
||||
Configure<AbpBundlingOptions>(options =>
|
||||
{
|
||||
options.StyleBundles.Configure(BasicThemeBundles.Styles.Global, bundle =>
|
||||
{
|
||||
bundle.AddFiles("/styles/global-styles.css");
|
||||
});
|
||||
});
|
||||
````
|
||||
|
||||
#### Override the Components
|
||||
|
||||
See the [User Interface Customization Guide](Customization-User-Interface.md) to learn how you can replace components, customize and extend the user interface.
|
||||
|
||||
### Copy & Customize
|
||||
|
||||
You can download the [source code](https://github.com/abpframework/abp/tree/dev/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic) of the Basic Theme, copy the project content into your solution, re-arrange the package/module dependencies (see the Installation section above to understand how it was installed to the project) and freely customize the theme based on your application requirements.
|
||||
|
||||
## See Also
|
||||
|
||||
* [Theming](Theming.md)
|
@ -0,0 +1,3 @@
|
||||
# ASP.NET Core MVC / Razor Pages: Branding
|
||||
|
||||
TODO
|
@ -1,3 +0,0 @@
|
||||
# Toolbars
|
||||
|
||||
TODO
|
@ -0,0 +1,263 @@
|
||||
# ASP.NET Core MVC / Razor Pages: Data Tables
|
||||
|
||||
A Data Table (aka Data Grid) is a UI component to show tabular data to the users. There are a lot of Data table components/libraries and **you can use any one you like** with the ABP Framework. However, the startup templates come with the [DataTables.Net](https://datatables.net/) library as **pre-installed and configured**. ABP Framework provides adapters for this library and make it easy to use with the API endpoints.
|
||||
|
||||
An example screenshot from the user management page that shows the user list in a data table:
|
||||
|
||||

|
||||
|
||||
## DataTables.Net Integration
|
||||
|
||||
First of all, you can follow the official documentation to understand how the [DataTables.Net](https://datatables.net/) works. This section will focus on the ABP addons & integration points rather than fully covering the usage of this library.
|
||||
|
||||
### A Quick Example
|
||||
|
||||
You can follow the [web application development tutorial](https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=MVC) for a complete example application that uses the DataTables.Net as the Data Table. This section shows a minimalist example.
|
||||
|
||||
You do nothing to add DataTables.Net library to the page since it is already added to the global [bundle](Bundling-Minification.md) by default.
|
||||
|
||||
First, add an `abp-table` as shown below, with an `id`:
|
||||
|
||||
````html
|
||||
<abp-table striped-rows="true" id="BooksTable"></abp-table>
|
||||
````
|
||||
|
||||
> `abp-table` is a [Tag Helper](Tag-Helpers/Index.md) defined by the ABP Framework, but a simple `<table...>` tag would also work.
|
||||
|
||||
Then call the `DataTable` plugin on the table selector:
|
||||
|
||||
````js
|
||||
var dataTable = $('#BooksTable').DataTable(
|
||||
abp.libs.datatables.normalizeConfiguration({
|
||||
serverSide: true,
|
||||
paging: true,
|
||||
order: [[1, "asc"]],
|
||||
searching: false,
|
||||
ajax: abp.libs.datatables.createAjax(acme.bookStore.books.book.getList),
|
||||
columnDefs: [
|
||||
{
|
||||
title: l('Actions'),
|
||||
rowAction: {
|
||||
items:
|
||||
[
|
||||
{
|
||||
text: l('Edit'),
|
||||
action: function (data) {
|
||||
///...
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
title: l('Name'),
|
||||
data: "name"
|
||||
},
|
||||
{
|
||||
title: l('PublishDate'),
|
||||
data: "publishDate",
|
||||
render: function (data) {
|
||||
return luxon
|
||||
.DateTime
|
||||
.fromISO(data, {
|
||||
locale: abp.localization.currentCulture.name
|
||||
}).toLocaleString();
|
||||
}
|
||||
},
|
||||
{
|
||||
title: l('Price'),
|
||||
data: "price"
|
||||
}
|
||||
]
|
||||
})
|
||||
);
|
||||
````
|
||||
|
||||
The example code above uses some ABP integration features those will be explained in the next sections.
|
||||
|
||||
### Configuration Normalization
|
||||
|
||||
`abp.libs.datatables.normalizeConfiguration` function takes a DataTables configuration and normalizes to simplify it;
|
||||
|
||||
* Sets `scrollX` option to `true`, if not set.
|
||||
* Sets `target` index for the column definitions.
|
||||
* Sets the `language` option to [localize](../../Localization.md) the table in the current language.
|
||||
|
||||
#### Default Configuration
|
||||
|
||||
`normalizeConfiguration` uses the default configuration. You can change the default configuration using the `abp.libs.datatables.defaultConfigurations` object. Example:
|
||||
|
||||
````js
|
||||
abp.libs.datatables.defaultConfigurations.scrollX = false;
|
||||
````
|
||||
|
||||
Here, the all configuration options;
|
||||
|
||||
* `scrollX`: `false` by default.
|
||||
* `dom`: Default value is `<"dataTable_filters"f>rt<"row dataTable_footer"<"col-auto"l><"col-auto"i><"col"p>>`.
|
||||
* `language`: A function that returns the localization text using the current language.
|
||||
|
||||
### AJAX Adapter
|
||||
|
||||
DataTables.Net has its own expected data format while getting results of an AJAX call to the server to get the table data. They are especially related how paging and sorting parameters are sent and received. ABP Framework also offers its own conventions for the client-server [AJAX](JavaScript-API/Ajax.md) communication.
|
||||
|
||||
The `abp.libs.datatables.createAjax` method (used in the example above) adapts request and response data format and perfectly works with the [Dynamic JavaScript Client Proxy](Dynamic-JavaScript-Client-Proxies.md) system.
|
||||
|
||||
This works automatically, so most of the times you don't need to know how it works. See the [DTO document](../../Data-Transfer-Objects.md) if you want to learn more about `IPagedAndSortedResultRequest`, `IPagedResult` and other standard interfaces and base DTO classes those are used in client to server communication.
|
||||
|
||||
### Row Actions
|
||||
|
||||
`rowAction` is an option defined by the ABP Framework to the column definitions to show a drop down button to take actions for a row in the table.
|
||||
|
||||
The example screenshot below shows the actions for each user in the user management table:
|
||||
|
||||

|
||||
|
||||
`rowAction` is defined as a part of a column definition:
|
||||
|
||||
````csharp
|
||||
{
|
||||
title: l('Actions'),
|
||||
rowAction: {
|
||||
//TODO: CONFIGURATION
|
||||
}
|
||||
},
|
||||
````
|
||||
|
||||
**Example: Show *Edit* and *Delete* actions for a book row**
|
||||
|
||||
````js
|
||||
{
|
||||
title: l('Actions'),
|
||||
rowAction: {
|
||||
items:
|
||||
[
|
||||
{
|
||||
text: l('Edit'),
|
||||
action: function (data) {
|
||||
//TODO: Open a modal to edit the book
|
||||
}
|
||||
},
|
||||
{
|
||||
text: l('Delete'),
|
||||
confirmMessage: function (data) {
|
||||
return "Are you sure to delete the book " + data.record.name;
|
||||
},
|
||||
action: function (data) {
|
||||
acme.bookStore.books.book
|
||||
.delete(data.record.id)
|
||||
.then(function() {
|
||||
abp.notify.info("Successfully deleted!");
|
||||
data.table.ajax.reload();
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
````
|
||||
|
||||
#### Action Items
|
||||
|
||||
`items` is an array of action definitions. An action definition can have the following options;
|
||||
|
||||
* `text`: The text (a `string`) for this action to be shown in the actions drop down.
|
||||
* `action`: A `function` that is executed when the user clicks to the action. The function takes a `data` argument that has the following fields;
|
||||
* `data.record`: This is the data object related to the row. You can access the data fields like `data.record.id`, `data.record.name`... etc.
|
||||
* `data.table`: The DataTables instance.
|
||||
* `confirmMessage`: A `function` (see the example above) that returns a message (`string`) to show a dialog to get a confirmation from the user before executing the `action`. Example confirmation dialog:
|
||||
|
||||

|
||||
|
||||
You can use the [localization](JavaScript-API/Localization.md) system to show a localized message.
|
||||
|
||||
* `visible`: A `bool` or a `function` that returns a `bool`. If the result is `false`, then the action is not shown in the actions dropdown. This is generally combined by the [authorization](JavaScript-API/Auth.md) system to hide the action if the user has no permission to take this action. Example:
|
||||
|
||||
````js
|
||||
visible: abp.auth.isGranted('BookStore.Books.Delete');
|
||||
````
|
||||
|
||||
If you define a `function`, then the `function` has two arguments: `record` (the data object of the related row) and the `table` (the DataTable instance). So, you can decide to show/hide the action dynamically, based on the row data and other conditions.
|
||||
|
||||
* `iconClass`: Can be used to show a font-icon, like a [Font-Awesome](https://fontawesome.com/) icon (ex: `fas fa-trash-alt`), near to the action text. Example screenshot:
|
||||
|
||||

|
||||
|
||||
* `enabled`: A `function` that returns a `bool` to disable the action. The `function` takes a `data` object with two fields: `data.record` is the data object related to the row and `data.table` is the DataTables instance.
|
||||
* `displayNameHtml`: Set this to `true` is the `text` value contains HTML tags.
|
||||
|
||||
There are some rules with the action items;
|
||||
|
||||
* If none of the action items is visible then the actions column is not rendered.
|
||||
|
||||
### Data Format
|
||||
|
||||
#### The Problem
|
||||
|
||||
See the *Creation Time* column in the example below:
|
||||
|
||||
````js
|
||||
{
|
||||
title: l('CreationTime'),
|
||||
data: "creationTime",
|
||||
render: function (data) {
|
||||
return luxon
|
||||
.DateTime
|
||||
.fromISO(data, {
|
||||
locale: abp.localization.currentCulture.name
|
||||
}).toLocaleString(luxon.DateTime.DATETIME_SHORT);
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
The `render` is a standard DataTables option to render the column content by a custom function. This example uses the [luxon](https://moment.github.io/luxon/) library (which is installed by default) to write a human readable value of the `creationTime` in the current user's language. Example output of the column:
|
||||
|
||||

|
||||
|
||||
If you don't define the render option, then the result will be ugly and not user friendly:
|
||||
|
||||

|
||||
|
||||
However, rendering a `DateTime` is almost same and repeating the same rendering logic everywhere is against to the DRY (Don't Repeat Yourself!) principle.
|
||||
|
||||
#### dataFormat Option
|
||||
|
||||
`dataFormat` column option specifies the data format that is used to render the column data. The same output could be accomplished using the following column definition:
|
||||
|
||||
````js
|
||||
{
|
||||
title: l('CreationTime'),
|
||||
data: "creationTime",
|
||||
dataFormat: 'datetime'
|
||||
}
|
||||
````
|
||||
|
||||
`dataFormat: 'datetime'` specifies the data format for this column. There are a few pre-defined `dataFormat`s:
|
||||
|
||||
* `boolean`: Shows a `check` icon for `true` and `times` icon for `false` value and useful to render `bool` values.
|
||||
* `date`: Shows date part of a `DateTime` value, formatted based on the current culture.
|
||||
* `datetime`: Shows date & time (excluding seconds) of a `DateTime` value, formatted based on the current culture.
|
||||
|
||||
### Default Renderers
|
||||
|
||||
`abp.libs.datatables.defaultRenderers` option allows you to define new data formats and set renderers for them.
|
||||
|
||||
**Example: Render male / female icons based on the gender**
|
||||
|
||||
````js
|
||||
abp.libs.datatables.defaultRenderers['gender'] = function(value) {
|
||||
if (value === 'f') {
|
||||
return '<i class="fa fa-venus"></i>';
|
||||
} else {
|
||||
return '<i class="fa fa-mars"></i>';
|
||||
}
|
||||
};
|
||||
````
|
||||
|
||||
Assuming that the possible values for a column data is `f` and `m`, the `gender` data format shows female/male icons instead of `f` and `m` texts. You can now set `dataFormat: 'gender'` for a column definition that has the proper data values.
|
||||
|
||||
> You can write the default renderers in a single JavaScript file and add it to the [Global Script Bundle](Bundling-Minification.md), so you can reuse them in all the pages.
|
||||
|
||||
## Other Data Grids
|
||||
|
||||
You can use any library you like. For example, [see this article](https://community.abp.io/articles/using-devextreme-components-with-the-abp-framework-zb8z7yqv) to learn how to use DevExtreme Data Grid in your applications.
|
@ -0,0 +1,58 @@
|
||||
# ASP.NET Core MVC / Razor Pages: Page Header
|
||||
|
||||
`IPageLayout` service can be used to set the page title, selected menu item and the breadcrumb items for a page. It's the [theme](Theming.md)'s responsibility to render these on the page.
|
||||
|
||||
## IPageLayout
|
||||
|
||||
`IPageLayout` can be injected in any page/view to set the page header properties.
|
||||
|
||||
### Page Title
|
||||
|
||||
Page Title can be set as shown in the example below:
|
||||
|
||||
````csharp
|
||||
@inject IPageLayout PageLayout
|
||||
@{
|
||||
PageLayout.Content.Title = "Book List";
|
||||
}
|
||||
````
|
||||
|
||||
* The Page Title is set to the HTML `title` tag (in addition to the [brand/application name](Branding.md)).
|
||||
* The theme may render the Page Title before the Page Content (not implemented by the Basic Theme).
|
||||
|
||||
### Breadcrumb
|
||||
|
||||
> **The [Basic Theme](Basic-Theme.md) currently doesn't implement the breadcrumbs.**
|
||||
|
||||
Breadcrumb items can be added to the `PageLayout.Content.BreadCrumb`.
|
||||
|
||||
**Example: Add Language Management to the breadcrumb items.**
|
||||
|
||||
````
|
||||
PageLayout.Content.BreadCrumb.Add("Language Management");
|
||||
````
|
||||
|
||||
The theme then renders the breadcrumb. An example render result can be:
|
||||
|
||||

|
||||
|
||||
* The Home icon is rendered by default. Set `PageLayout.Content.BreadCrumb.ShowHome` to `false` to hide it.
|
||||
* Current Page name (got from the `PageLayout.Content.Title`) is added as the last by default. Set `PageLayout.Content.BreadCrumb.ShowCurrent` to `false` to hide it.
|
||||
|
||||
Any item that you add is inserted between Home and Current Page items. You can add as many item as you need. `BreadCrumb.Add(...)` method gets three parameters:
|
||||
|
||||
* `text`: The text to show for the breadcrumb item.
|
||||
* `url` (optional): A URL to navigate to, if the user clicks to the breadcrumb item.
|
||||
* `icon` (optional): An icon class (like `fas fa-user-tie` for Font-Awesome) to show with the `text`.
|
||||
|
||||
### The Selected Menu Item
|
||||
|
||||
> **The [Basic Theme](Basic-Theme.md) currently doesn't implement the selected menu item since it is not applicable to the top menu which is the only option for the Basic Theme for now.**
|
||||
|
||||
You can set the Menu Item name related to this page:
|
||||
|
||||
````csharp
|
||||
PageLayout.Content.MenuItemName = "BookStore.Books";
|
||||
````
|
||||
|
||||
Menu item name should match a unique menu item name defined using the [Navigation / Menu](Navigation-Menu.md) system. In this case, it is expected from the theme to make the menu item "active" in the main menu.
|
@ -1,3 +1,74 @@
|
||||
# Toolbars
|
||||
|
||||
TODO
|
||||
The Toolbar system is used to define **toolbars** on the user interface. Modules (or your application) can add **items** to a toolbar, then the [theme](Theming.md) renders the toolbar on the **layout**.
|
||||
|
||||
There is only one **standard toolbar** named "Main" (defined as a constant: `StandardToolbars.Main`). The [Basic Theme](Basic-Theme) renders the main toolbar as shown below:
|
||||
|
||||

|
||||
|
||||
In the screenshot above, there are two items added to the main toolbar: Language switch component & user menu. You can add your own items here.
|
||||
|
||||
## Example: Add a Notification Icon
|
||||
|
||||
In this example, we will add a **notification (bell) icon** to the left of the language switch item. A item in the toolbar should be a **view component**. So, first, create a new view component in your project:
|
||||
|
||||

|
||||
|
||||
**NotificationViewComponent.cs**
|
||||
|
||||
````csharp
|
||||
public class NotificationViewComponent : AbpViewComponent
|
||||
{
|
||||
public async Task<IViewComponentResult> InvokeAsync()
|
||||
{
|
||||
return View("/Pages/Shared/Components/Notification/Default.cshtml");
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
**Default.cshtml**
|
||||
|
||||
````xml
|
||||
<div id="MainNotificationIcon" style="color: white; margin: 8px;">
|
||||
<i class="far fa-bell"></i>
|
||||
</div>
|
||||
````
|
||||
|
||||
Now, we can create a class implementing the `IToolbarContributor` interface:
|
||||
|
||||
````csharp
|
||||
public class MyToolbarContributor : IToolbarContributor
|
||||
{
|
||||
public Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
|
||||
{
|
||||
if (context.Toolbar.Name == StandardToolbars.Main)
|
||||
{
|
||||
context.Toolbar.Items
|
||||
.Insert(0, new ToolbarItem(typeof(NotificationViewComponent)));
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
This class adds the `NotificationViewComponent` as the first item in the `Main` toolbar.
|
||||
|
||||
Finally, you need to add this contributor to the `AbpToolbarOptions`, in the `ConfigureServices` of your [module](../../Module-Development-Basics.md):
|
||||
|
||||
````csharp
|
||||
Configure<AbpToolbarOptions>(options =>
|
||||
{
|
||||
options.Contributors.Add(new MyToolbarContributor());
|
||||
});
|
||||
````
|
||||
|
||||
That's all, you will see the notification icon on the toolbar when you run the application:
|
||||
|
||||

|
||||
|
||||
`NotificationViewComponent` in this sample simply returns a view without any data. In real life, you probably want to **query database** (or call an HTTP API) to get notifications and pass to the view. If you need, you can add a `JavaScript` or `CSS` file to the global [bundle](Bundling-Minification.md) for your toolbar item.
|
||||
|
||||
## IToolbarManager
|
||||
|
||||
`IToolbarManager` is used to render the toolbar. It returns the toolbar items by a toolbar name. This is generally used by the [themes](Theming.md) to render the toolbar on the layout.
|
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 9.6 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 14 KiB |
@ -1,194 +1,160 @@
|
||||
## 在AspNet Core MVC Web Application中使用ABP
|
||||
|
||||
本教程将介绍如何开始以最少的依赖关系开始使用ABP开发.
|
||||
|
||||
通常情况下你需要下载一个 ***[启动模板](Getting-Started-AspNetCore-MVC-Template.md)***
|
||||
|
||||
### 创建一个新项目
|
||||
|
||||
1. 使用Visual Studio创建一个空的AspNet Core Web Application:
|
||||
|
||||

|
||||
|
||||
2. 选择空模板
|
||||
|
||||

|
||||
|
||||
你可以选择其它模板,但是我想要从一个简洁的项目演示它.
|
||||
|
||||
### 安装 Volo.Abp.AspNetCore.Mvc 包
|
||||
|
||||
Volo.Abp.AspNetCore.Mvc是ABP集成AspNet Core MVC的包,请安装它到你项目中:
|
||||
|
||||
````
|
||||
Install-Package Volo.Abp.AspNetCore.Mvc
|
||||
````
|
||||
|
||||
### 创建ABP模块
|
||||
|
||||
ABP是一个模块化框架,它需要一个**启动 (根) 模块**继承自``AbpModule``:
|
||||
|
||||
````C#
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.AspNetCore.Mvc;
|
||||
using Volo.Abp.Modularity;
|
||||
|
||||
namespace BasicAspNetCoreApplication
|
||||
{
|
||||
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
|
||||
public class AppModule : AbpModule
|
||||
{
|
||||
public override void OnApplicationInitialization(
|
||||
ApplicationInitializationContext context)
|
||||
{
|
||||
var app = context.GetApplicationBuilder();
|
||||
var env = context.GetEnvironment();
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Error");
|
||||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseRouting();
|
||||
app.UseConfiguredEndpoints();
|
||||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
``AppModule`` 是应用程序启动模块的好名称(建议你的启动模块也使用这个命名).
|
||||
|
||||
ABP的包定义了这个模块类,模块可以依赖其它模块.在上面的代码中 ``AppModule`` 依赖于 ``AbpAspNetCoreMvcModule`` (模块存在于Volo.Abp.AspNetCore.Mvc包中). 安装新的ABP的包后添加``DependsOn``是很常见的做法.
|
||||
|
||||
我们在此模块类中配置ASP.NET Core管道,而不是Startup类中.
|
||||
|
||||
### 启动类
|
||||
|
||||
接下来修改启动类集成ABP模块系统:
|
||||
|
||||
````C#
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BasicAspNetCoreApplication
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public IServiceProvider ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddApplication<AppModule>();
|
||||
|
||||
return services.BuildServiceProviderFromFactory();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.InitializeApplication();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
修改``ConfigureServices``方法的返回值为``IServiceProvider``(默认是``void``).这个修改允许我们替换AspNet Core的依赖注入框架. (参阅下面的Autofac集成部分). ``services.AddApplication<AppModule>()``添加了所有模块中定义的全部服务.
|
||||
|
||||
``app.InitializeApplication()`` 调用 ``Configure`` 方法初始化并启动应用程序
|
||||
|
||||
### Hello World!
|
||||
|
||||
上面的应用程序没有什么功能,让我们创建一个MVC控制器实现一些功能:
|
||||
|
||||
````C#
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Volo.Abp.AspNetCore.Mvc;
|
||||
|
||||
namespace BasicAspNetCoreApplication.Controllers
|
||||
{
|
||||
public class HomeController : AbpController
|
||||
{
|
||||
public IActionResult Index()
|
||||
{
|
||||
return Content("Hello World!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
如果运行这个应用程序你会在页面中看到"Hello World!".
|
||||
|
||||
Derived ``HomeController`` from ``AbpController`` instead of standard ``Controller`` class. This is not required, but ``AbpController`` class has useful base properties and methods to make your development easier.
|
||||
|
||||
从``AbpController``派生``HomeController`` 而不是继承自``Controller``类.虽然这不是强制要求,但是``AbpController``类有很多有用的有属性和方法,使你的开发更容易.
|
||||
|
||||
### 使用 Autofac 依赖注入框架
|
||||
|
||||
虽然AspNet Core的依赖注入(DI)系统适用于基本要求,但Autofac提供了属性注入和方法拦截等高级功能,这些功能是ABP执行高级应用程序框架功能所必需的.
|
||||
|
||||
用Autofac取代AspNet Core的DI系统并集成到ABP非常简单.
|
||||
|
||||
1. 安装 Volo.Abp.Autofac 包
|
||||
|
||||
````
|
||||
Install-Package Volo.Abp.Autofac
|
||||
````
|
||||
|
||||
2. 添加 ``AbpAutofacModule`` 依赖
|
||||
|
||||
````C#
|
||||
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
|
||||
[DependsOn(typeof(AbpAutofacModule))] // 在模块上添加依赖AbpAutofacModule
|
||||
public class AppModule : AbpModule
|
||||
{
|
||||
...
|
||||
}
|
||||
````
|
||||
|
||||
3. 修改在``Startup``类下的``services.AddApplication<AppModule>();``如下所示:
|
||||
|
||||
````C#
|
||||
services.AddApplication<AppModule>(options =>
|
||||
{
|
||||
options.UseAutofac(); // 集成 Autofac
|
||||
});
|
||||
````
|
||||
|
||||
4. 更新 `Program.cs`代码, 不再使用`WebHost.CreateDefaultBuilder()`方法(因为它使用默认的DI容器):
|
||||
|
||||
````csharp
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
/*
|
||||
https://github.com/aspnet/AspNetCore/issues/4206#issuecomment-445612167
|
||||
CurrentDirectoryHelpers 文件位于: \framework\src\Volo.Abp.AspNetCore.Mvc\Microsoft\AspNetCore\InProcess\CurrentDirectoryHelpers.cs
|
||||
当升级到ASP.NET Core 3.0的时候将会删除这个类.
|
||||
*/
|
||||
CurrentDirectoryHelpers.SetCurrentDirectory();
|
||||
|
||||
BuildWebHostInternal(args).Run();
|
||||
}
|
||||
public static IWebHost BuildWebHostInternal(string[] args) =>
|
||||
new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIIS()
|
||||
.UseIISIntegration()
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
}
|
||||
````
|
||||
|
||||
|
||||
### 源码
|
||||
|
||||
从[此处](https://github.com/abpframework/abp-samples/tree/master/BasicAspNetCoreApplication)获取本教程中创建的示例项目的源代码.
|
||||
# 在AspNet Core MVC Web Application中使用ABP
|
||||
|
||||
本教程将介绍如何开始以最少的依赖关系开始使用ABP开发.
|
||||
|
||||
通常情况下你需要下载一个 **[启动模板](Getting-Started-AspNetCore-MVC-Template.md)**
|
||||
|
||||
## 创建一个新项目
|
||||
|
||||
1. 使用Visual Studio 2019 (16.4.0+)创建一个新的AspNet Core Web Application:
|
||||
|
||||

|
||||
|
||||
2. 配置新的项目:
|
||||
|
||||

|
||||
|
||||
3. 完成创建:
|
||||
|
||||

|
||||
|
||||
|
||||
## 安装 Volo.Abp.AspNetCore.Mvc 包
|
||||
|
||||
Volo.Abp.AspNetCore.Mvc是ABP集成AspNet Core MVC的包,请安装它到你项目中:
|
||||
|
||||
````
|
||||
Install-Package Volo.Abp.AspNetCore.Mvc
|
||||
````
|
||||
|
||||
## 创建ABP模块
|
||||
|
||||
ABP是一个模块化框架,它需要一个**启动 (根) 模块**继承自``AbpModule``:
|
||||
|
||||
````C#
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.AspNetCore.Mvc;
|
||||
using Volo.Abp.Modularity;
|
||||
|
||||
namespace BasicAspNetCoreApplication
|
||||
{
|
||||
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
|
||||
public class AppModule : AbpModule
|
||||
{
|
||||
public override void OnApplicationInitialization(
|
||||
ApplicationInitializationContext context)
|
||||
{
|
||||
var app = context.GetApplicationBuilder();
|
||||
var env = context.GetEnvironment();
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Error");
|
||||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseRouting();
|
||||
app.UseConfiguredEndpoints();
|
||||
}
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
``AppModule`` 是应用程序启动模块的好名称.
|
||||
|
||||
ABP的包定义了这个模块类,模块可以依赖其它模块.在上面的代码中 ``AppModule`` 依赖于 ``AbpAspNetCoreMvcModule`` (模块存在于[Volo.Abp.AspNetCore.Mvc](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc)包中). 安装新的ABP的包后添加``DependsOn``是很常见的做法.
|
||||
|
||||
我们在此模块类中配置ASP.NET Core管道,而不是Startup类中.
|
||||
|
||||
### 启动类
|
||||
|
||||
接下来修改启动类集成ABP模块系统:
|
||||
|
||||
````C#
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BasicAspNetCoreApplication
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddApplication<AppModule>();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.InitializeApplication();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
``services.AddApplication<AppModule>()``添加了所有``AppModule``模块中定义的全部服务.
|
||||
|
||||
``Configure``方法中的``app.InitializeApplication()``完成初始化并启动应用程序.
|
||||
|
||||
## 运行应用程序!
|
||||
|
||||
启动该应用,它将按预期运行.
|
||||
|
||||
## 使用 Autofac 依赖注入框架
|
||||
|
||||
虽然AspNet Core的依赖注入(DI)系统适用于基本要求,但[Autofac](https://autofac.org/)提供了属性注入和方法拦截等高级功能,这些功能是ABP执行高级应用程序框架功能所必需的.
|
||||
|
||||
用Autofac取代AspNet Core的DI系统并集成到ABP非常简单.
|
||||
|
||||
1. 安装 [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) 包
|
||||
|
||||
````
|
||||
Install-Package Volo.Abp.Autofac
|
||||
````
|
||||
|
||||
2. 添加 ``AbpAutofacModule`` 依赖
|
||||
|
||||
````C#
|
||||
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
|
||||
[DependsOn(typeof(AbpAutofacModule))] // 在模块上添加依赖AbpAutofacModule
|
||||
public class AppModule : AbpModule
|
||||
{
|
||||
...
|
||||
}
|
||||
````
|
||||
|
||||
3. 修改``Program.cs``以使用Autofac:
|
||||
|
||||
````C#
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace BasicAspNetCoreApplication
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
})
|
||||
.UseAutofac(); // 添加这一行
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
## 源码
|
||||
|
||||
从[此处](https://github.com/abpframework/abp-samples/tree/master/BasicAspNetCoreApplication)获取本教程中创建的示例项目的源代码.
|
||||
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="BlazoriseMyGet" value="https://www.myget.org/F/blazorise/api/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="BlazoriseMyGet" value="https://www.myget.org/F/blazorise/api/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|