mirror of https://github.com/abpframework/abp.git
224 changed files with 1404 additions and 922 deletions
@ -0,0 +1,142 @@ |
|||||
|
# ABP Framework 4.0 RC Has Been Published based on .NET 5.0! |
||||
|
|
||||
|
Today, we have released the [ABP Framework](https://abp.io/) (and the [ABP Commercial](https://commercial.abp.io/)) `4.0.0-rc.1` that is based on the **.NET 5.0**. This blog post introduces the new features and important changes in the new version. |
||||
|
|
||||
|
> **The planned release date for the [4.0.0 final](https://github.com/abpframework/abp/milestone/45) version is November 26, 2020**. |
||||
|
|
||||
|
## Get Started with the 4.0 RC.1 |
||||
|
|
||||
|
If you want to try the version `4.0.0-rc.1` today, follow the steps below; |
||||
|
|
||||
|
1) **Upgrade** the ABP CLI to the version `4.0.0-rc.1` using a command line terminal: |
||||
|
|
||||
|
````bash |
||||
|
dotnet tool update Volo.Abp.Cli -g --version 4.0.0-rc.1 |
||||
|
```` |
||||
|
|
||||
|
**or install** if you haven't installed before: |
||||
|
|
||||
|
````bash |
||||
|
dotnet tool install Volo.Abp.Cli -g --version 4.0.0-rc.1 |
||||
|
```` |
||||
|
|
||||
|
2) Create a **new application** with the `--preview` option: |
||||
|
|
||||
|
````bash |
||||
|
abp new BookStore --preview |
||||
|
```` |
||||
|
|
||||
|
See the [ABP CLI documentation](https://docs.abp.io/en/abp/3.3/CLI) for all the available options. |
||||
|
|
||||
|
> You can also use the *Direct Download* tab on the [Get Started](https://abp.io/get-started) page by selecting the **Preview checkbox**. |
||||
|
|
||||
|
## Migrating From 3.x to 4.0 |
||||
|
|
||||
|
The version 4.0 comes with some major changes including the **migration from .NET Core 3.1 to .NET 5.0**. |
||||
|
|
||||
|
We've prepared a **detailed [migration document](https://docs.abp.io/en/abp/4.0/Migration-Guides/Abp-4_0)** to explain all the changes and the actions you need to take while upgrading your existing solutions. |
||||
|
|
||||
|
## What's new with the ABP Framework 4.0 |
||||
|
|
||||
|
### The Blazor UI |
||||
|
|
||||
|
The Blazor UI is now stable and officially supported. The [web application development tutorial](https://docs.abp.io/en/abp/4.0/Tutorials/Part-1?UI=Blazor) has been updated based on the version 4.0. |
||||
|
|
||||
|
#### abp bundle command |
||||
|
|
||||
|
Introducing the `abp bundle` CLI command to manage static JavaScript & CSS file dependencies of a Blazor application. This command is currently used to add the dependencies to the `index.html` file in the dependency order by respecting to modularity. In the next version it will automatically unify & minify the files. The documentation is being prepared. |
||||
|
|
||||
|
#### Removed the JQuery & Bootstrap JavaScript |
||||
|
|
||||
|
Removed JQuery & Bootstrap JavaScript dependencies for the Blazor UI. |
||||
|
|
||||
|
>There are some other changes in the startup template and some public APIs. Follow the [Migration Guide](https://docs.abp.io/en/abp/4.0/Migration-Guides/Abp-4_0) to apply changes for existing solutions that you're upgrading from the version 3.3. While we will continue to make improvements add new features, we no longer make breaking changes on the existing APIs until the version 5.0. |
||||
|
|
||||
|
#### Others |
||||
|
|
||||
|
A lot of minor and major improvements have been done for the Blazor UI. Some of them are listed below: |
||||
|
|
||||
|
* Implemented `IComponentActivator` to resolve the component from the `IServiceProvider`. So, you can now inject dependencies into the constructor of your razor component. |
||||
|
* Introduced the `AbpComponentBase` base class that you derive your components from. It has useful base properties that you can use in your pages/components. |
||||
|
* Introduced `IUiNotificationService` service to show toast notifications on the UI. |
||||
|
* Improved the `IUiMessageService` to show message & confirmation dialogs. |
||||
|
|
||||
|
### System.Text.Json |
||||
|
|
||||
|
ABP Framework 4.0 uses the System.Text.Json by default as the JSON serialization library. It, actually, using a hybrid approach: Continues to use the Newtonsoft.Json when it needs to use the features not supported by the System.Text.Json. |
||||
|
|
||||
|
Follow the [Migration Guide](https://docs.abp.io/en/abp/4.0/Migration-Guides/Abp-4_0) to learn how to configure to use the Newtonsoft.Json for some specific types or switch back to the Newtonsoft.Json as the default JSON serializer. |
||||
|
|
||||
|
### Identity Server 4 Upgrade |
||||
|
|
||||
|
ABP Framework upgrades the [IdentityServer4](https://www.nuget.org/packages/IdentityServer4) library from 3.x to 4.1.1 with the ABP Framework version 4.0. IdentityServer 4.x has a lot of changes. Some of them are **breaking changes in the data structure**. |
||||
|
|
||||
|
Follow the [Migration Guide](https://docs.abp.io/en/abp/4.0/Migration-Guides/Abp-4_0) to upgrade existing solutions. |
||||
|
|
||||
|
### Creating a New Module Inside the Application |
||||
|
|
||||
|
ABP CLI has now a command to create a new module and add it to an existing solution. In this way, you can create modular applications easier than before. |
||||
|
|
||||
|
Example: Create a *ProductManagement* module into your solution. |
||||
|
|
||||
|
````bash |
||||
|
abp add-module ProductManagement --new --add-to-solution-file |
||||
|
```` |
||||
|
|
||||
|
Execute this command in a terminal in the root folder of your solution. If you don't specify the `--add-to-solution-file` option, then the module projects will not be added to the main solution, but the project references still be added. In this case, you need to open the module's solution to develop the module. |
||||
|
|
||||
|
See the [CLI document](https://docs.abp.io/en/abp/4.0/CLI) for other options. |
||||
|
|
||||
|
### WPF Startup Template |
||||
|
|
||||
|
Introducing the WPF startup template for the ABP Framework. Use the ABP CLI new command to create a new WPF application: |
||||
|
|
||||
|
````bash |
||||
|
abp new MyWpfApp -t wpf |
||||
|
```` |
||||
|
|
||||
|
This is a minimalist, empty project template that is integrated to the ABP Framework. |
||||
|
|
||||
|
### New Languages |
||||
|
|
||||
|
**Thanks to the contributors** from the ABP Community, the framework modules and the startup template have been localized to **German** (by [Alexander Pilhar](https://github.com/alexanderpilhar) & [Nico Lachmuth](https://github.com/tntwist)) and **Spanish** (by [Jose Manuel Gonzalez](https://github.com/jmglezgz)) languages. |
||||
|
|
||||
|
### Other Notes |
||||
|
|
||||
|
* Since [Mongo2Go](https://github.com/Mongo2Go/Mongo2Go) library not supports transactions, you can use transactions in unit tests for MongoDB. |
||||
|
|
||||
|
## What's new with the ABP Commercial 4.0 |
||||
|
|
||||
|
### The Blazor UI |
||||
|
|
||||
|
The Blazor UI for the ABP Commercial is also becomes stable and feature rich with the version 4.0; |
||||
|
|
||||
|
* [ABP Suite](https://commercial.abp.io/tools/suite) now supports to generate CRUD pages for the Blazor UI. |
||||
|
* Completed the [Lepton Theme](https://commercial.abp.io/themes) for the Blazor UI. |
||||
|
* Implemented the [File Management](https://commercial.abp.io/modules/Volo.FileManagement) module for the Blazor UI. |
||||
|
|
||||
|
### The ABP Suite |
||||
|
|
||||
|
While creating create/edit modals with a navigation property, we had two options: A dropdown to select the target entity and a modal to select the entity by searching with a data table. |
||||
|
|
||||
|
Dropdown option now supports **lazy load, search and auto-complete**. In this way, selecting a navigation property becomes much easier and supports large data sets on the dropdown. |
||||
|
|
||||
|
**Example: Select an author while creating a new book** |
||||
|
|
||||
|
 |
||||
|
|
||||
|
With the new version, you can **disable backend code generation** on CRUD page generation. This is especially useful if you want to regenerate the page with a different UI framework, but don't want to regenerate the server side code. |
||||
|
|
||||
|
### Identity Server Management UI Revised |
||||
|
|
||||
|
Completely revised the Identity Server Management UI based on the IDS 4.x changes. |
||||
|
|
||||
|
## About the Next Release |
||||
|
|
||||
|
The next feature version, `4.1.0`, will mostly focus on completing the missing documents, fixing bugs, performance optimizations and improving the Blazor UI features. The planned preview release date for the version `4.1.0` is December 10 and the final (stable) version release date is December 24. |
||||
|
|
||||
|
Follow the [GitHub milestones](https://github.com/abpframework/abp/milestones) for all the planned ABP Framework version release dates. |
||||
|
|
||||
|
## Feedback |
||||
|
|
||||
|
Please check out the ABP Framework 4.0.0 RC and [provide feedback](https://github.com/abpframework/abp/issues/new) to help us to release a more stable version. **The planned release date for the [4.0.0 final](https://github.com/abpframework/abp/milestone/45) version is November 26**. |
||||
|
After Width: | Height: | Size: 28 KiB |
@ -0,0 +1,11 @@ |
|||||
|
# Angular UI 3.3 to 4.0 Migration Guide |
||||
|
|
||||
|
### Removed the Angular Account Module Public UI |
||||
|
|
||||
|
Angular UI is using the Authorization Code Flow to authenticate since the version 3.1.0 by default. Starting from the version 4.0, this is becoming the only option, because it is the recommended way of authenticating SPAs. |
||||
|
|
||||
|
If you haven't done it yet, see [this post](https://blog.abp.io/abp/ABP-Framework-v3.1-RC-Has-Been-Released) to change the authentication of your application. |
||||
|
|
||||
|
### Removed the SessionState |
||||
|
|
||||
|
Use `SessionStateService` instead of the `SessionState`. See [this issue](https://github.com/abpframework/abp/issues/5606) for details. |
||||
@ -0,0 +1,88 @@ |
|||||
|
# Blazor UI 3.3 to 4.0 Migration Guide |
||||
|
|
||||
|
## Startup Template Changes |
||||
|
|
||||
|
These changes are required to manually applied in your own solution. It would be easier if you create a new solution based on 4.0 with the same name of your current solution then compare the files. |
||||
|
|
||||
|
### Csproj File / Dependencies |
||||
|
|
||||
|
* Add `<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>` to the `PropertyGroup` section of your project (`.csproj`) file. |
||||
|
* Update the `Blazorise.*` packages to the latest version (to the latest RC for the ABP 4.0 preview). |
||||
|
|
||||
|
### wwwroot/index.html |
||||
|
|
||||
|
There are some changes made in the index.html file; |
||||
|
|
||||
|
* Removed JQuery & Bootstrap JavaScript dependencies |
||||
|
* Replaced Bootstrap and FontAwesome imports with local files instead of CDN usages. |
||||
|
* Re-arranged some ABP CSS file locations. |
||||
|
* Introduced the `abp bundle` CLI command to manage global Style/Script file imports. |
||||
|
|
||||
|
Follow the steps below to apply the changes; |
||||
|
|
||||
|
1. Add the bundle contributor class into your project (it will be slightly different based on your solution namespaces): |
||||
|
|
||||
|
````csharp |
||||
|
using Volo.Abp.Bundling; |
||||
|
|
||||
|
namespace MyCompanyName.MyProjectName.Blazor |
||||
|
{ |
||||
|
public class MyProjectNameBundleContributer : IBundleContributer |
||||
|
{ |
||||
|
public void AddScripts(BundleContext context) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void AddStyles(BundleContext context) |
||||
|
{ |
||||
|
context.Add("main.css"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
If you are using another global style/script files, add them here. |
||||
|
|
||||
|
2. Remove all the `<link...>` elements and replace with the following comment tags: |
||||
|
|
||||
|
````html |
||||
|
<!--ABP:Styles--> |
||||
|
<!--/ABP:Styles--> |
||||
|
```` |
||||
|
|
||||
|
3. Remove all the `<script...>` elements and replace with the following comment tags: |
||||
|
|
||||
|
````html |
||||
|
<!--ABP:Scripts--> |
||||
|
<!--/ABP:Scripts--> |
||||
|
```` |
||||
|
|
||||
|
4. Execute the following command in a terminal in the root folder of the Blazor project (`.csproj`) file (ensure that you're using the ABP CLI version 4.0): |
||||
|
|
||||
|
````bash |
||||
|
abp bundle |
||||
|
```` |
||||
|
|
||||
|
This will fill in the `Styles` and `Scripts` tags based on the dependencies. |
||||
|
|
||||
|
5. You can clean the `blazor-error-ui` related sections from your `main.css` file since they are not needed anymore. |
||||
|
|
||||
|
### The Root Element |
||||
|
|
||||
|
This change is optional but recommended. |
||||
|
|
||||
|
* Change `<app>...</app>` to `<div id="ApplicationContainer">...</div>` in the `wwwroot/index.html`. |
||||
|
* Change `builder.RootComponents.Add<App>("app");` to `builder.RootComponents.Add<App>("#ApplicationContainer");` in the *YourProjectBlazorModule.cs*. |
||||
|
|
||||
|
## AbpCrudPageBase Changes |
||||
|
|
||||
|
If you've derived your pages from the `AbpCrudPageBase` class, then you may need to apply the following changes; |
||||
|
|
||||
|
- `OpenEditModalAsync` method gets `EntityDto` instead of id (`Guid`) parameter. Pass `context` instead of `context.Id`. |
||||
|
- `DeleteEntityAsync` method doesn't display confirmation dialog anymore. You can use the new `EntityActions` component in Data Grids to show confirmation messages. You can also inject `IUiMessageService` to your page or component and call the `ConfirmAsync` explicitly. |
||||
|
- Added `GetListInput` as a base property that is used to filter while getting the entities from the server. |
||||
|
|
||||
|
## Others |
||||
|
|
||||
|
- Refactored namespaces for some Blazor components ([#6015](https://github.com/abpframework/abp/issues/6015)). |
||||
|
- Removed Async Suffix from IUiMessageService ([#6123](https://github.com/abpframework/abp/pull/6123)). |
||||
@ -0,0 +1,6 @@ |
|||||
|
# MVC / Razor Pages UI 3.3 to 4.0 Migration Guide |
||||
|
|
||||
|
## Use IBrandingProvider in the Volo.Abp.UI Package |
||||
|
|
||||
|
This will be a breaking change for MVC UI, but very easy to fix. `IBrandingProvider` is being moved from `Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components` to `Volo.Abp.Ui.Branding` namespace. So, just update the namespace imports. |
||||
|
|
||||
@ -0,0 +1,140 @@ |
|||||
|
# Form Validation |
||||
|
|
||||
|
Reactive forms in ABP Angular UI are validated by [ngx-validate](https://www.npmjs.com/package/@ngx-validate/core) and helper texts are shown automatically based on validation rules and error blueprints. You do not have to add any elements or components to your templates. The library handles that for you. Here is how the experience is: |
||||
|
|
||||
|
<img alt="The ngx-validate library validates an Angular reactive form and an error text appears under each wrong input based on the validation rule and the error blueprint." src="./images/form-validation---error-display-user-experience.gif" width="990px" style="max-width:100%"> |
||||
|
|
||||
|
## How to Add New Error Messages |
||||
|
|
||||
|
You can add a new error message by providing the `VALIDATION_BLUEPRINTS` injection token from your root module. |
||||
|
|
||||
|
```js |
||||
|
import { VALIDATION_BLUEPRINTS } from "@ngx-validate/core"; |
||||
|
|
||||
|
@NgModule({ |
||||
|
// rest of the module metadata |
||||
|
|
||||
|
providers: [ |
||||
|
// other providers |
||||
|
{ |
||||
|
provide: VALIDATION_BLUEPRINTS, |
||||
|
useValue: { |
||||
|
uniqueUsername: "::AlreadyExists[{%{{{ username }}}%}]", |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}) |
||||
|
export class AppModule {} |
||||
|
``` |
||||
|
|
||||
|
When a [validator](https://angular.io/guide/form-validation#defining-custom-validators) or an [async validator](https://angular.io/guide/form-validation#creating-asynchronous-validators) returns an error with the key given to the error blueprints (`uniqueUsername` here), the validation library will be able to display an error message after localizing according to the given key and interpolation params. The result will look like this: |
||||
|
|
||||
|
<img alt="An already taken username is entered while creating new user and a custom error message appears under the input after validation." src="./images/form-validation---new-error-message.gif" width="990px" style="max-width:100%"> |
||||
|
|
||||
|
In this example; |
||||
|
|
||||
|
- Localization key is `::AlreadyExists`. |
||||
|
- The interpolation param is `username`. |
||||
|
- Localization resource is defined as `"AlreadyExists": "Sorry, “{0}” already exists."`. |
||||
|
- And the validator should return `{ uniqueUsername: { username: "admin" } }` as the error object. |
||||
|
|
||||
|
## How to Change Existing Error Messages |
||||
|
|
||||
|
You can overwrite an existing error message by providing `VALIDATION_BLUEPRINTS` injection token from your root module. Let's imagine you have a custom localization resource for required inputs. |
||||
|
|
||||
|
```json |
||||
|
"RequiredInput": "Oops! We need this input." |
||||
|
``` |
||||
|
|
||||
|
To use this instead of the built-in required input message, all you need to do is the following. |
||||
|
|
||||
|
```js |
||||
|
import { VALIDATION_BLUEPRINTS } from "@ngx-validate/core"; |
||||
|
|
||||
|
@NgModule({ |
||||
|
// rest of the module metadata |
||||
|
|
||||
|
providers: [ |
||||
|
// other providers |
||||
|
{ |
||||
|
provide: VALIDATION_BLUEPRINTS, |
||||
|
useValue: { |
||||
|
required: "::RequiredInput", |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}) |
||||
|
export class AppModule {} |
||||
|
``` |
||||
|
|
||||
|
The error message will look like this: |
||||
|
|
||||
|
<img alt="A required field is cleared and the custom error message appears under the input." src="./images/form-validation---overwrite-error-message.gif" width="990px" style="max-width:100%"> |
||||
|
|
||||
|
## How to Disable Validation on a Form |
||||
|
|
||||
|
If you want to validate a form manually, you can always disable automatic validation on it. All you need to do is place `skipValidation` on the form element. |
||||
|
|
||||
|
```html |
||||
|
<form [formGroup]="form" skipValidation> |
||||
|
<!-- form fields here --> |
||||
|
</form> |
||||
|
``` |
||||
|
|
||||
|
## How to Disable Validation on a Specific Field |
||||
|
|
||||
|
Validation works on any element or component with a `formControl` or `formControlName` directive. You can disable automatic validation on a specific field by placing `skipValidation` on the input element or component. |
||||
|
|
||||
|
```html |
||||
|
<input type="text" formControlName="name" skipValidation /> |
||||
|
``` |
||||
|
|
||||
|
## How to Use a Custom Error Component |
||||
|
|
||||
|
First, build a custom error component. Extending the existing `ValidationErrorComponent` would make it easier. |
||||
|
|
||||
|
```js |
||||
|
import { ValidationErrorComponent } from "@abp/ng.theme.basic"; |
||||
|
import { ChangeDetectionStrategy, Component } from "@angular/core"; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: "app-validation-error", |
||||
|
template: ` |
||||
|
<div |
||||
|
class="font-weight-bold font-italic px-1 invalid-feedback" |
||||
|
*ngFor="let error of abpErrors; trackBy: trackByFn" |
||||
|
> |
||||
|
{%{{{ error.message | abpLocalization: error.interpoliteParams }}}%} |
||||
|
</div> |
||||
|
`, |
||||
|
changeDetection: ChangeDetectionStrategy.OnPush, |
||||
|
}) |
||||
|
export class ErrorComponent extends ValidationErrorComponent {} |
||||
|
``` |
||||
|
|
||||
|
Then, declare and provide it in your root module. |
||||
|
|
||||
|
```js |
||||
|
import { VALIDATION_ERROR_TEMPLATE } from "@ngx-validate/core"; |
||||
|
|
||||
|
@NgModule({ |
||||
|
// rest of the module metadata |
||||
|
|
||||
|
declarations: [ |
||||
|
// other declarables |
||||
|
ErrorComponent, |
||||
|
], |
||||
|
providers: [ |
||||
|
// other providers |
||||
|
{ |
||||
|
provide: VALIDATION_ERROR_TEMPLATE, |
||||
|
useValue: ErrorComponent, |
||||
|
}, |
||||
|
], |
||||
|
}) |
||||
|
export class AppModule {} |
||||
|
``` |
||||
|
|
||||
|
The error message will be bold and italic now: |
||||
|
|
||||
|
<img alt="A required field is cleared and a bold and italic error message appears." src="./images/form-validation---custom-error-template.gif" width="990px" style="max-width:100%"> |
||||
|
After Width: | Height: | Size: 494 KiB |
|
After Width: | Height: | Size: 906 KiB |
|
After Width: | Height: | Size: 466 KiB |
|
After Width: | Height: | Size: 488 KiB |
@ -0,0 +1,15 @@ |
|||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Vue; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.VeeValidate |
||||
|
{ |
||||
|
[DependsOn(typeof(VueScriptContributor))] |
||||
|
public class VeeValidateScriptContributor : BundleContributor |
||||
|
{ |
||||
|
public override void ConfigureBundle(BundleConfigurationContext context) |
||||
|
{ |
||||
|
context.Files.Add("/libs/vee-validate.js/vee-validate.full.js"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Vue |
||||
|
{ |
||||
|
public class VueScriptContributor : BundleContributor |
||||
|
{ |
||||
|
public override void ConfigureBundle(BundleConfigurationContext context) |
||||
|
{ |
||||
|
context.Files.Add("/libs/vue.js/vue.js"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
using System; |
||||
|
using System.Buffers; |
||||
|
using System.Buffers.Text; |
||||
|
using System.Text.Json; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace Volo.Abp.Json.SystemTextJson.JsonConverters |
||||
|
{ |
||||
|
public class AbpStringToBooleanConverter : JsonConverter<bool> |
||||
|
{ |
||||
|
public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
||||
|
{ |
||||
|
if (reader.TokenType == JsonTokenType.String) |
||||
|
{ |
||||
|
var span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; |
||||
|
if (Utf8Parser.TryParse(span, out bool b1, out var bytesConsumed) && span.Length == bytesConsumed) |
||||
|
{ |
||||
|
return b1; |
||||
|
} |
||||
|
|
||||
|
if (bool.TryParse(reader.GetString(), out var b2)) |
||||
|
{ |
||||
|
return b2; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return reader.GetBoolean(); |
||||
|
} |
||||
|
|
||||
|
public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options) |
||||
|
{ |
||||
|
var newOptions = new JsonSerializerOptions(options); |
||||
|
newOptions.Converters.Remove(this); |
||||
|
var entityConverter = (JsonConverter<bool>)newOptions.GetConverter(typeof(bool)); |
||||
|
entityConverter.Write(writer, value, newOptions); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
using System; |
||||
|
using System.Text.Json; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace Volo.Abp.Json.SystemTextJson.JsonConverters |
||||
|
{ |
||||
|
public class AbpStringToEnumConverter : JsonConverter<object> |
||||
|
{ |
||||
|
private readonly JsonStringEnumConverter _innerJsonStringEnumConverter; |
||||
|
|
||||
|
public AbpStringToEnumConverter() |
||||
|
: this(namingPolicy: null, allowIntegerValues: true) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public AbpStringToEnumConverter(JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true) |
||||
|
{ |
||||
|
_innerJsonStringEnumConverter = new JsonStringEnumConverter(namingPolicy, allowIntegerValues); |
||||
|
} |
||||
|
|
||||
|
public override bool CanConvert(Type typeToConvert) |
||||
|
{ |
||||
|
return typeToConvert.IsEnum; |
||||
|
} |
||||
|
|
||||
|
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
||||
|
{ |
||||
|
var newOptions = new JsonSerializerOptions(options); |
||||
|
newOptions.Converters.Remove(this); |
||||
|
newOptions.Converters.Add(_innerJsonStringEnumConverter.CreateConverter(typeToConvert, newOptions)); |
||||
|
return JsonSerializer.Deserialize(ref reader, typeToConvert, newOptions); |
||||
|
} |
||||
|
|
||||
|
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) |
||||
|
{ |
||||
|
var newOptions = new JsonSerializerOptions(options); |
||||
|
newOptions.Converters.Remove(this); |
||||
|
JsonSerializer.Serialize(writer, value, newOptions); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.OpenApi.Models; |
||||
|
using Swashbuckle.AspNetCore.SwaggerGen; |
||||
|
|
||||
|
namespace Microsoft.Extensions.DependencyInjection |
||||
|
{ |
||||
|
public static class AbpSwaggerGenServiceCollectionExtensions |
||||
|
{ |
||||
|
public static IServiceCollection AddAbpSwaggerGenWithOAuth( |
||||
|
this IServiceCollection services, |
||||
|
[NotNull] string authority, |
||||
|
[NotNull] Dictionary<string, string> scopes, |
||||
|
Action<SwaggerGenOptions> setupAction = null) |
||||
|
{ |
||||
|
return services.AddSwaggerGen( |
||||
|
options => |
||||
|
{ |
||||
|
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme |
||||
|
{ |
||||
|
Type = SecuritySchemeType.OAuth2, |
||||
|
Flows = new OpenApiOAuthFlows |
||||
|
{ |
||||
|
AuthorizationCode = new OpenApiOAuthFlow |
||||
|
{ |
||||
|
AuthorizationUrl = new Uri($"{authority.EnsureEndsWith('/')}connect/authorize"), |
||||
|
Scopes = scopes, |
||||
|
TokenUrl = new Uri($"{authority.EnsureEndsWith('/')}connect/token") |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement |
||||
|
{ |
||||
|
{ |
||||
|
new OpenApiSecurityScheme |
||||
|
{ |
||||
|
Reference = new OpenApiReference |
||||
|
{ |
||||
|
Type = ReferenceType.SecurityScheme, |
||||
|
Id = "oauth2" |
||||
|
} |
||||
|
}, |
||||
|
Array.Empty<string>() |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
setupAction?.Invoke(options); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Mvc.Abstractions; |
||||
|
using Microsoft.AspNetCore.Mvc.Filters; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.Response |
||||
|
{ |
||||
|
public class TestResultFilter : Attribute, IAsyncActionFilter |
||||
|
{ |
||||
|
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) |
||||
|
{ |
||||
|
await next(); |
||||
|
context.Result = new ObjectResult("TestResultFilter"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,6 +1,6 @@ |
|||||
{ |
{ |
||||
"sdk": { |
"sdk": { |
||||
"version": "5.0.100-rc.2.20479.15", |
"version": "5.0.100", |
||||
"rollForward": "latestFeature" |
"rollForward": "latestFeature" |
||||
} |
} |
||||
} |
} |
||||
|
|||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue