Swashbuckle.AspNetCore.Filters
8.0.2
dotnet add package Swashbuckle.AspNetCore.Filters --version 8.0.2
NuGet\Install-Package Swashbuckle.AspNetCore.Filters -Version 8.0.2
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
paket add Swashbuckle.AspNetCore.Filters --version 8.0.2
#r "nuget: Swashbuckle.AspNetCore.Filters, 8.0.2"
// Install Swashbuckle.AspNetCore.Filters as a Cake Addin #addin nuget:?package=Swashbuckle.AspNetCore.Filters&version=8.0.2 // Install Swashbuckle.AspNetCore.Filters as a Cake Tool #tool nuget:?package=Swashbuckle.AspNetCore.Filters&version=8.0.2
Swashbuckle.AspNetCore.Filters
📣 Rename to Swashbuckle.AspNetCore.Filters |
---|
This project was formerly called Swashbuckle.AspNetCore.Examples, but it has grown from there to become a grab-bag of various filters I have created (or copied) since I started used Swashbuckle in 2015. So I have renamed it. |
This library contains a bunch of filters for Swashbuckle.AspNetCore.
- Add example requests https://mattfrear.com/2016/01/25/generating-swagger-example-requests-with-swashbuckle/
- Add example responses https://mattfrear.com/2015/04/21/generating-swagger-example-responses-with-swashbuckle/
- Add security info to each operation that has an
[Authorize]
attribute, allowing you to send OAuth2 bearer tokens via Swagger-UI https://mattfrear.com/2018/07/21/add-an-authorization-header-to-your-swagger-ui-with-swashbuckle-revisited/ - Add any old request header to all requests
- Add any old response header to all responses
- Add an indicator to each endpoint to show if it has an
[Authorize]
attribute (and for which policies and roles)
Table of Contents
- Changelog
- Where to get it
- What's included
- Installation
- How to use
- How to use - Request examples
- DO NOT USE THIS FILTER UNLESS YOU HAVE TO
- How to use - Response examples
- AGAIN, DO NOT USE THIS FILTER UNLESS YOU HAVE TO
- How to use - Multiple examples
- How to use - Security requirements filter
- How to use - Request Header
- How to use - Response headers
- How to use - Authorization summary
- Pascal case or Camel case?
- Render Enums as strings
- Advanced: Examples with Dependency injection
Changelog
See the CHANGELOG.md.
Where to get it
From NuGet.
Version of Swashbuckle you're using | You'll want this version of this package |
---|---|
Swashbuckle 1.0 - 5.5 | https://www.nuget.org/packages/Swashbuckle.Examples/ |
Swashbuckle.AspNetCore version 1.0.0 - 2.5.0 | https://www.nuget.org/packages/Swashbuckle.AspNetCore.Examples/ |
Swashbuckle.AspNetCore version 3.0.0 | https://www.nuget.org/packages/Swashbuckle.AspNetCore.Filters/ |
Swashbuckle.AspNetCore version 4.0.0 and above | https://www.nuget.org/packages/Swashbuckle.AspNetCore.Filters/ Version >= 4.5.1 |
Swashbuckle.AspNetCore version 5.0.0-beta and above | https://www.nuget.org/packages/Swashbuckle.AspNetCore.Filters/ Version >= 5.0.0-beta |
What's included
Request example
Populate swagger's paths.path.[http-verb].requestBody.content.[content-type].example
with whatever object you like.
This is great for manually testing and demoing your API as it will prepopulate the request with some useful data, so that when you click the example request in order to populate the form, instead of getting an autogenerated request like this:
You’ll get your desired example, with useful valid data, like this:
You can see the example output in the underlying swagger.json file, which you can get to by starting your solution and navigating to swagger/v1/swagger.json
As of version 5.0.0-beta, XML examples are also supported.
Response example
Allows you to add custom data to the example response shown in Swagger. So instead of seeing the default boring data like so:
You'll see some more realistic data (or whatever you want):
As of version 5.0.0-beta, XML examples are also supported.
Security requirements filter
Adds security information to each operation so that you can send an Authorization header to your API. Useful for API endpoints that have JWT token authentication. e.g.
Add a request header
Adds any string to your request headers for all requests. I use this for adding a correlationId to all requests.
Add a response header
Allows you to specify response headers for any operation
Add Authorization to Summary
If you use the [Authorize]
attribute to your controller or to any actions, then (Auth) is added to the action's summary,
along with any specified policies or roles.
Installation
Install the NuGet package
In the ConfigureServices method of Startup.cs, inside your
AddSwaggerGen
call, enable whichever filters you need
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
// [SwaggerRequestExample] & [SwaggerResponseExample]
// version < 3.0 like this: c.OperationFilter<ExamplesOperationFilter>();
// version 3.0 like this: c.AddSwaggerExamples(services.BuildServiceProvider());
// version > 4.0 like this:
c.ExampleFilters();
c.OperationFilter<AddHeaderOperationFilter>("correlationId", "Correlation Id for the request", false); // adds any string you like to the request headers - in this case, a correlation id
c.OperationFilter<AddResponseHeadersFilter>(); // [SwaggerResponseHeader]
var filePath = Path.Combine(AppContext.BaseDirectory, "WebApi.xml");
c.IncludeXmlComments(filePath); // standard Swashbuckle functionality, this needs to be before c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>()
c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>(); // Adds "(Auth)" to the summary so that you can see which endpoints have Authorization
// or use the generic method, e.g. c.OperationFilter<AppendAuthorizeToSummaryOperationFilter<MyCustomAttribute>>();
// add Security information to each operation for OAuth2
c.OperationFilter<SecurityRequirementsOperationFilter>();
// or use the generic method, e.g. c.OperationFilter<SecurityRequirementsOperationFilter<MyCustomAttribute>>();
// if you're using the SecurityRequirementsOperationFilter, you also need to tell Swashbuckle you're using OAuth2
c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Description = "Standard Authorization header using the Bearer scheme. Example: \"bearer {token}\"",
In = ParameterLocation.Header,
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});
});
}
- If you want to use the Request and Response example filters (and have called
c.ExampleFilters()
above), then you MUST also call
services.AddSwaggerExamplesFromAssemblyOf<MyExample>();
or
services.AddSwaggerExamplesFromAssemblyOf(typeof(MyExample));
or
services.AddSwaggerExamplesFromAssemblies(Assembly.GetEntryAssembly());
This will register your examples with the ServiceProvider.
Serialize Swagger in the 2.0 format
There are two ways to tell Swashbuckle.AspNetCore to output the swagger.json in the legacy Swagger 2.0 format:
app.UseSwagger(c => c.SerializeAsV2 = true);
// OR
services.Configure<SwaggerOptions>(c => c.SerializeAsV2 = true);
If you want to SerializeAsV2 and you're using my Request example filter then you must call services.Configure<SwaggerOptions>(c => c.SerializeAsV2 = true);
.
How to use
How to use - Request examples
DO NOT USE THIS FILTER UNLESS YOU HAVE TO
Since May 2018, Swashbuckle.AspNetCore supports adding examples via XML comments:
public class Product
{
/// <summary>
/// The name of the product
/// </summary>
/// <example>Men's basketball shoes</example>
public string Name { get; set; }
This works for request examples and response examples, and it even works for example querystring and route parameters, i.e. on GET requests!
Example in a querystring on GET:
Example request body in a POST:
Example response:
And soon (April 2020, once my Swashbuckle.AspNetCore PR has been released) you'll be able to add examples for primitive types on the querystring too, e.g.
/// <param name="id" example="123">The product id</param>
[HttpGet("{id}")]
public Product GetById(int id)
See the instructions on Swashbuckle.AspNetCore's Readme.
Therefore, I recommend that you move away from using my ExamplesOperationFilter
. Personally, I don't use it any more and would like to deprecate it.
However, you may have a use case where XML comments doesn't work for you, e.g.
- You want to generate examples at runtime not design time
- You need XML request examples (not JSON)
- You want examples to be added to the schema under the path, rather than the schema under the component
- Some other ReDoc issue which I don't understand as I don't use ReDoc...
In which case, read on...
Automatic annotation
Version 4.0 and above supports automatic annotation.
Let's say you have a controller action which takes some input from the body, in this case a DeliveryOptionsSearchModel
:
[HttpPost]
public async Task<IHttpActionResult> DeliveryOptionsForAddress([FromBody]DeliveryOptionsSearchModel search)
Then all you need to do is implement IExamplesProvider<DeliveryOptionsSearchModel>
:
public class DeliveryOptionsSearchModelExample : IExamplesProvider<DeliveryOptionsSearchModel>
{
public DeliveryOptionsSearchModel GetExamples()
{
return new DeliveryOptionsSearchModel
{
Lang = "en-GB",
Currency = "GBP",
Address = new AddressModel
{
Address1 = "1 Gwalior Road",
Locality = "London",
Country = "GB",
PostalCode = "SW15 1NP"
}
};
}
And that's it.
Manual annotation
Alternatively, if you want to be more explicit, you can use the SwaggerRequestExample
attribute. This is how it was done in versions 1.0 - 3.0. Any manual annotations will override automatic annotations.
Decorate your controller methods with the included SwaggerRequestExample
attribute:
[HttpPost]
[SwaggerRequestExample(typeof(DeliveryOptionsSearchModel), typeof(DeliveryOptionsSearchModelExample))]
public async Task<IHttpActionResult> DeliveryOptionsForAddress([FromBody]DeliveryOptionsSearchModel search)
Now implement a IExamplesProvider<T>
, in this case via a DeliveryOptionsSearchModelExample which will generate the example data. It should return the type you specified when you specified the [SwaggerRequestExample]
.
public class DeliveryOptionsSearchModelExample : IExamplesProvider<DeliveryOptionsSearchModel>
{
public DeliveryOptionsSearchModel GetExamples()
{
return new DeliveryOptionsSearchModel
{
Lang = "en-GB",
Currency = "GBP",
Address = new AddressModel
{
Address1 = "1 Gwalior Road",
Locality = "London",
Country = "GB",
PostalCode = "SW15 1NP"
},
Items = new[]
{
new ItemModel
{
ItemId = "ABCD",
ItemType = ItemType.Product,
Price = 20,
Quantity = 1,
RestrictedCountries = new[] { "US" }
}
}
};
}
In the Swagger document, this will populate the operation's requestBody content type example property. https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#mediaTypeObject
Here's what the OpenApi 3.0 spec says about it:
Field Name | Type | Description |
---|---|---|
example | Any | Example of the media type. The example object SHOULD be in the correct format as specified by the media type. The example object is mutually exclusive of the examples object. Furthermore, if referencing a schema which contains an example, the example value SHALL override the example provided by the schema. |
List Request examples
As of version 2.4, List<T>
request examples are supported. For any List<T>
in the request, you may define a SwaggerRequestExample for T
.
Your IExamplesProvider should only return a single T
and not a List<T>
.
Working example:
[SwaggerRequestExample(typeof(PeopleRequest), typeof(ListPeopleRequestExample))]
public IEnumerable<PersonResponse> GetPersonList([FromBody]List<PeopleRequest> peopleRequest)
{
// and then:
public class ListPeopleRequestExample : IExamplesProvider<PeopleRequest>
{
public PeopleRequest GetExamples()
{
return new PeopleRequest { Title = Title.Mr, Age = 24, FirstName = "Dave in a list", Income = null };
}
}
How to use - Response examples
AGAIN, DO NOT USE THIS FILTER UNLESS YOU HAVE TO
I repeat my earlier assertion - Since May 2018, Swashbuckle.AspNetCore supports adding examples via XML comments.
If you still want to use it, read on...
Automatic annotation
Version 4.0 supports automatic annotation.
If it's obvious which type your action returns, then no ProducesResponseType
or SwaggerResponse
attributes need to be specified, e.g.
public async Task<ActionResult<IEnumerable<Country>>> Get(string lang)
// or public ActionResult<IEnumerable<Country>> Get(string lang)
// or public IEnumerable<Country> Get(string lang)
Manual annotation
Alternatively, if you want to be more explicit, you can use the SwaggerResponseExample
attribute. This is how it was done in versions 1.0 - 3.0. Any manual annotations will override automatic annotations.
Decorate your methods with the new SwaggerResponseExample attribute:
[SwaggerResponse(200, "The list of countries", typeof(IEnumerable<Country>))]
// or, like this [ProducesResponseType(typeof(IEnumerable<Country>), 200)]
[SwaggerResponseExample(200, typeof(CountryExamples))]
[SwaggerResponse(400, type: typeof(IEnumerable<ErrorResource>))]
public async Task<HttpResponseMessage> Get(string lang)
For manual annotation implement IExamplesProvider<T>
to generate the example data
public class CountryExamples : IExamplesProvider<List<Country>>
{
public List<Country> GetExamples()
{
return new List<Country>
{
new Country { Code = "AA", Name = "Test Country" },
new Country { Code = "BB", Name = "And another" }
};
}
}
In the Swagger document, this will populate the operation's responses content example object. The spec for this says:
Field Pattern | Type | Description |
---|---|---|
example | Any | Example of the media type. The example object SHOULD be in the correct format as specified by the media type. The example object is mutually exclusive of the examples object. Furthermore, if referencing a schema which contains an example, the example value SHALL override the example provided by the schema. |
Example response for application/json mimetype of a Pet data type:
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pet"
},
"example": "{\r\n \"name\": \"Lassie\",\r\n \"type\": \"Dog\",\r\n \"color\": \"Black\",\r\n \"gender\": \"Femail\",\r\n \"breed\": \"Collie\" \r\n}"
},
Known issues
- Request examples are not shown for querystring parameters (i.e. HTTP GET requests, or for querystring parameters for POST, PUT etc methods). Request examples will only be shown in request body. You can use Swashbuckle.AspNetCore's built-in XML comments to add examples for primitive types.
How to use - Multiple examples
Sometimes more than a single example are desirable for an API. In this case you can use IMultipleExamplesProvider<T>
rather than IExamplesProvider<T>
to return multiple examples. The example provider class is still located in the same way (automatic or manual annotation), but the GetExamples()
call returns an enumerated list of examples along with their name and optional summary. To reduce boilerplate, it is recommended to use yield return
for each example value. Every returned SwaggerExample<T>
should have different value of Name
property.
public class DeliveryOptionsSearchModelExample : IMultipleExamplesProvider<DeliveryOptionsSearchModel>
{
public IEnumerable<SwaggerExample<DeliveryOptionsSearchModel>> GetExamples()
{
// An example without a summary.
yield return SwaggerExample.Create(
"Great Britain",
"Here's an optional description" // optional description - Markdown is supported
new DeliveryOptionsSearchModel
{
Lang = "en-GB",
Currency = "GBP",
Address = new AddressModel
{
Address1 = "1 Gwalior Road",
Locality = "London",
Country = "GB",
PostalCode = "SW15 1NP"
}
}
);
// An example with a summary.
yield return SwaggerExample.Create(
"United States",
"A minor former colony of Great Britain",
new DeliveryOptionsSearchModel
{
Lang = "en-US",
Currency = "USD",
Address = new AddressModel
{
Address1 = "123 Main Street",
Locality = "New York",
Country = "US",
PostalCode = "10001"
}
},
);
}
Note that UIs may choose to display the summary in different ways; in ReDoc, for example, the summary (if present) replaces the name in the UI.
How to use - Security requirements filter
First you need to already have OAuth2 configured correctly, and some of your controllers and actions locked down with the [Authorize]
attribute.
N.B. globally registered Authorization filters are not detected.
Then you need to tell Swagger that you're using OAuth2, as shown in the Installation section above:
services.AddSwaggerGen(c =>
{
c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Description = "Standard Authorization header using the Bearer scheme. Example: \"bearer {token}\"",
In = ParameterLocation.Header,
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});
This adds a securityDefinition to the bottom of the Swagger document, which Swagger-UI renders as an "Authorize" button, which when clicked brings up the Authorize dialog box shown above.
Then, when you enable the SecurityRequirementsOperationFilter:
// add Security information to each operation for OAuth2
c.OperationFilter<SecurityRequirementsOperationFilter>();
It adds a security property to each operation, which renders in Swagger-UI as a padlock next to the operation:
By default, the SecurityRequirementsOperationFilter also adds 401 and 403 to each operation that has [Authorize]
on it:
If you don't want to do that you can pass false when you configure it:
c.OperationFilter<SecurityRequirementsOperationFilter>(false);
How to use - Request Header
When you enable the filter in your Startup.cs
, as per the Installation section above, you can specify the name (string)
and description (string) of the new header parameter, as well as whether it is required or not (bool).
This will add the input box to every controller action.
How to use - Response headers
Specify one or more [SwaggerResponseHeader]
attributes on your controller action.
You can specify the status code (int), header name (string), type (string), description (string) and format (string).
See the OpenAPI Specification spec for information on DataTypes: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#dataTypes
[SwaggerResponseHeader(StatusCodes.Status200OK, "Location", "string", "Location of the newly created resource")]
[SwaggerResponseHeader(200, "ETag", "string", "An ETag of the resource")]
[SwaggerResponseHeader(429, "Retry-After", "integer", "Indicates how long to wait before making a new request.", "int32")]
[SwaggerResponseHeader(new int[] { 200, 401, 403, 404 }, "CustomHeader", "string", "A custom header")]
public IHttpActionResult GetPerson(PersonRequest personRequest)
{
How to use - Authorization summary
Specify [Authorization]
headers on either a Controller:
[Authorize]
public class ValuesController : Controller
or on an action:
[Authorize("Customer")]
public PersonResponse GetPerson([FromBody]PersonRequest personRequest)
You can optionally specify policies [Authorize("Customer")]
or roles [Authorize(Roles = "Customer")]
and they will be added to the Summary too.
Pascal case or Camel case?
The default is camelCase. If you want PascalCase you can pass in a DefaultContractResolver
like so:
[SwaggerResponseExample(200, typeof(PersonResponseExample), typeof(DefaultContractResolver))]
The above is no longer supported - it will output Examples using whichever JSON serializer your controllers are configured with
in services.AddControllers()
.
Minimal APIs
If you're using .NET 5 and above, we now default to use System.Text.Json.JsonSerializerDefaults.Web
when rendering examples,
which means you'll get camelCase. PascalCase is not supported.
Render Enums as strings
By default enum
s will output their integer values. If you want to output strings you can pass in a StringEnumConverter
like so:
[SwaggerResponseExample(200, typeof(PersonResponseExample), jsonConverter: typeof(StringEnumConverter))]
The above is no longer supported - it will output Examples using whichever JSON serializer your controllers are configured with
in services.AddControllers()
.
Advanced: Examples with Dependency injection
If for some reason you need to have examples with DI (for example, to read them from a database), you can use constructor injection:
internal class PersonRequestExample : IExamplesProvider
{
private readonly IHostingEnvironment _env;
public PersonRequestExample(IHostingEnvironment env)
{
_env = env;
}
public object GetExamples()
{
return new PersonRequest { Age = 24, FirstName = _env.IsDevelopment() ? "Development" : "Production", Income = null };
}
}
Then, you should register the Swagger examples via the extension methods:
services.AddSwaggerExamplesFromAssemblyOf<PersonRequestExample>();
or
services.AddSwaggerExamplesFromAssemblyOf(typeof(PersonRequestExample));
or
services.AddSwaggerExamplesFromAssemblies(Assembly.GetEntryAssembly());
If you are using services.AddSwaggerExamples()
, then you would have to manually register your IExamplesProvider
class:
services.AddSingleton<PersonRequestExample>();
The FromAssemblyOf<T>
extension method is the recommended approach.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 is compatible. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETCoreApp 3.1
- Microsoft.Extensions.DependencyInjection (>= 2.1.0)
- Microsoft.OpenApi (>= 1.3.1)
- Scrutor (>= 3.3.0)
- Swashbuckle.AspNetCore.Filters.Abstractions (>= 8.0.2)
- Swashbuckle.AspNetCore.SwaggerGen (>= 5.0.0)
-
.NETStandard 2.0
- Microsoft.Extensions.DependencyInjection (>= 2.1.0)
- Microsoft.OpenApi (>= 1.3.1)
- Scrutor (>= 3.3.0)
- Swashbuckle.AspNetCore.Filters.Abstractions (>= 8.0.2)
- Swashbuckle.AspNetCore.SwaggerGen (>= 5.0.0)
-
net5.0
- Microsoft.Extensions.DependencyInjection (>= 2.1.0)
- Microsoft.OpenApi (>= 1.3.1)
- Scrutor (>= 3.3.0)
- Swashbuckle.AspNetCore.Filters.Abstractions (>= 8.0.2)
- Swashbuckle.AspNetCore.SwaggerGen (>= 5.0.0)
NuGet packages (231)
Showing the top 5 NuGet packages that depend on Swashbuckle.AspNetCore.Filters:
Package | Downloads |
---|---|
Elsa.Server.Api
Elsa is a set of workflow libraries and tools that enable lean and mean workflowing capabilities in any .NET Core application. This package provides API endpoints to interact with the workflow host. |
|
Be.Vlaanderen.Basisregisters.AspNetCore.Swagger
Swagger helpers. |
|
Coder.Extension
Coder扩展程序,包含:AutoMapper,Log,CsRedis,Swagger(Knife4j),Cors,Autofac,Hangfire,TimedJob,CAP,SqlSugar,Polly(超时,重试,熔断,降级)等扩展服务和中间件。 |
|
Swashbuckle.AspNetCore.JsonMultipartFormDataSupport
Support JSON Multipart data in Swashbuckle |
|
Apprio.Enablement.Web.Api
Package Description |
GitHub repositories (33)
Showing the top 5 popular GitHub repositories that depend on Swashbuckle.AspNetCore.Filters:
Repository | Stars |
---|---|
Kareadita/Kavita
Kavita is a fast, feature rich, cross platform reading server. Built with the goal of being a full solution for all your reading needs. Setup your own server and share your reading collection with your friends and family.
|
|
anjoy8/Blog.Core
💖 ASP.NET Core 8.0 全家桶教程,前后端分离后端接口,vue教程姊妹篇,官方文档:
|
|
geffzhang/NanoFabric
基于Consul + .NET Core + Polly + Ocelot + Exceptionless + IdentityServer等开源项目的微服务开发框架
|
|
featbit/featbit
Enterprise-level feature flag platform that you can self-host. Get started - free.
|
|
Meowv/Blog
🤣本项目有不同开发版本,最新版底层基于 abp vNext 搭建和免费开源跨平台框架 .NET5 进行开发,使用 MongoDB 存储数据,Redis 缓存数据。项目采用前后端分离的模式进行开发,API 遵循 RESTful 接口规范,页面使用 Blazor 进行开发,可作为 .NET Core 入门项目进行学习。If you liked `Blog` project or if it helped you, please give a star ⭐️ for this repository. 👍👍👍
|
Version | Downloads | Last updated |
---|---|---|
8.0.2 | 4,806,351 | 5/1/2024 |
8.0.1 | 2,178,783 | 2/16/2024 |
8.0.0 | 1,197,891 | 1/9/2024 |
7.0.12 | 2,460,356 | 10/24/2023 |
7.0.11 | 1,351,627 | 9/7/2023 |
7.0.10 | 3,864 | 9/7/2023 |
7.0.9 | 17,988 | 9/6/2023 |
7.0.8 | 1,447,706 | 7/14/2023 |
7.0.7 | 10,320 | 7/13/2023 |
7.0.6 | 9,116,216 | 11/13/2022 |
7.0.5 | 3,302,852 | 8/22/2022 |
7.0.4 | 949,342 | 8/1/2022 |
7.0.3 | 2,500,986 | 5/24/2022 |
7.0.2 | 12,960,924 | 4/3/2021 |
7.0.1 | 3,334 | 4/3/2021 |
7.0.0 | 214,163 | 4/3/2021 |
6.1.0 | 2,379,461 | 2/15/2021 |
6.0.1 | 4,020,003 | 10/16/2020 |
6.0.0 | 624,990 | 9/27/2020 |
5.1.2 | 3,200,983 | 6/25/2020 |
5.1.1 | 3,230,927 | 4/12/2020 |
5.1.0 | 420,276 | 4/5/2020 |
5.0.2 | 1,137,456 | 2/24/2020 |
5.0.1 | 9,806 | 2/24/2020 |
5.0.0 | 1,392,206 | 1/21/2020 |
5.0.0-rc9 | 202,295 | 12/30/2019 |
5.0.0-rc8 | 707,976 | 8/2/2019 |
5.0.0-rc7 | 14,933 | 7/26/2019 |
5.0.0-rc6 | 565 | 7/26/2019 |
5.0.0-rc5 | 116,505 | 7/24/2019 |
5.0.0-rc4 | 83,790 | 7/13/2019 |
5.0.0-rc3 | 32,472 | 6/10/2019 |
5.0.0-rc2 | 110,696 | 5/30/2019 |
5.0.0-beta | 34,476 | 4/24/2019 |
4.5.5 | 2,886,320 | 3/3/2019 |
4.5.4 | 182,816 | 2/8/2019 |
4.5.3 | 137,989 | 1/14/2019 |
4.5.2 | 305,831 | 12/2/2018 |
4.5.1 | 60,128 | 11/14/2018 |
4.5.0 | 11,375 | 11/12/2018 |
4.4.0 | 5,803 | 11/8/2018 |
4.3.1 | 176,979 | 10/8/2018 |
4.3.0 | 83,690 | 9/14/2018 |
4.2.0 | 78,009 | 8/15/2018 |
4.1.0 | 31,557 | 8/6/2018 |
4.0.3 | 4,108 | 8/3/2018 |
4.0.2 | 10,357 | 7/26/2018 |
4.0.1 | 31,621 | 7/24/2018 |
4.0.0 | 9,963 | 7/23/2018 |
3.1.0 | 10,327 | 7/21/2018 |
3.0.4 | 8,549 | 7/18/2018 |
3.0.3 | 2,357 | 7/17/2018 |
3.0.2 | 1,163 | 7/15/2018 |
3.0.1 | 11,158 | 7/15/2018 |
Bug fix #244