mirror of https://github.com/abpframework/abp.git
836 changed files with 6701 additions and 2265 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,177 @@ |
|||
# VoloDocs |
|||
|
|||
## What is VoloDocs? |
|||
|
|||
VoloDocs is a cross-platform web application that allows you to easily create beautiful documentation and build developer communities. It simplifies software documentation with the help of GitHub integration. You use the power of GitHub for versioning, hosting of your docs. You let your users to edit a document. |
|||
|
|||
## Main Features |
|||
|
|||
- Serves documents from your GitHub repository. |
|||
- Supports Markdown / HTML document formatting. |
|||
- Supports versioning (integrated to GitHub releases). |
|||
- Supports multiple projects. |
|||
- Allows users to edit a document on GitHub. |
|||
- Cross-platform; deployable to Windows / Linux / macOS. |
|||
|
|||
## GitHub Repository |
|||
|
|||
It's free & open-source. You can browse VoloDocs source-code and contribute on GitHub: |
|||
|
|||
https://github.com/abpframework/abp/tree/master/modules/docs |
|||
|
|||
## Download |
|||
|
|||
You can download the VoloDocs release from the following links: |
|||
|
|||
http://apps.abp.io/VoloDocs/VoloDocs.win-x64.zip - **Windows 64 bit** |
|||
|
|||
http://apps.abp.io/VoloDocs/VoloDocs.win-x86.zip - **Windows 32 bit** |
|||
|
|||
http://apps.abp.io/VoloDocs/VoloDocs.osx-x64.zip - **MacOS** |
|||
|
|||
http://apps.abp.io/VoloDocs/VoloDocs.linux-x64.zip - **Linux** |
|||
|
|||
Notice that, all installations are self-contained deployments. It means all the required third-party dependencies along with the version of .NET Core is included. So you don't need to install any .NET Core SDK / Runtime. |
|||
|
|||
## Folder Structure |
|||
|
|||
When you extract the `VoloDocs.*.zip` file, you will see a `Web` folder and a `Migrator` folder. The `Web` folder contains the website files and `Migrator` contains the application to build your database. Before publishing your website, you need to create a new database or update your existing database to the latest. If this is the first time you install VoloDocs, `Migrator` will create a new database for you, otherwise it updates to the latest version. The only setting you need to configure, is the `ConnectionString` which is located in the `appsettings.json` file. See the next section to learn how to configure your VoloDocs application. |
|||
|
|||
## Steps by Step Deployment |
|||
|
|||
- ### Database Migration |
|||
|
|||
To update your existing database or create your initial database, go to `Migrator` folder in your VoloDocs directory. |
|||
|
|||
Open `appsettings.json` in your text editor and set your database connection string. If you don't know how to write the connection string for your database system, you can check out https://www.connectionstrings.com/. |
|||
|
|||
After you set your connection string, run `Migrate.bat` for Windows platform and `VoloDocs.Migrator` for other operating systems. That's it now configure your website. |
|||
|
|||
- ### Configuring Website |
|||
|
|||
Go to `Web` folder in your VoloDocs directory. Open `appsettings.json` in your text editor. Set your connection string (same as in the `Migrator`'s `appsettings.json`). Set `title` of your website. This will be written on the left-upper corner of your website. That's it! Now you can publish your website. |
|||
|
|||
If you want to run |
|||
|
|||
- ### Deploying Website |
|||
|
|||
In the previous step, you created or updated your database. Ensure that your database exists on the specified connection string. |
|||
|
|||
- #### Deploying to IIS |
|||
|
|||
- Move `Web` folder to your `wwwroot ` folder. |
|||
- Rename `Web` folder to `VoloDocs` (Now you have `C:\inetpub\wwwroot\VoloDocs`). |
|||
- The `VoloDocs` application pool is being created automatically. Open **Application Pools** and double click `VoloDocs` application pool and set |
|||
- **.NET CLR version**: `No Managed Code` |
|||
- **Managed pipeline mode**: `Integrated` |
|||
|
|||
 |
|||
|
|||
|
|||
|
|||
- If you get the below error, it means don't have the hosting bundle installed on the server. See [this document](https://docs.microsoft.com/aspnet/core/host-and-deploy/iis/#install-the-net-core-hosting-bundle) to learn how to install it or [download Hosting Bundle](https://www.microsoft.com/net/permalink/dotnetcore-current-windows-runtime-bundle-installer) and run on your server. |
|||
|
|||
``` |
|||
Handler "aspNetCore" has a bad module "AspNetCoreModuleV2" in its module list using IIS |
|||
``` |
|||
|
|||
- Further information about hosting VoloDocs check out [Microsoft's official document for hosting ASP.NET Core application on IIS](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis). |
|||
|
|||
- #### Deploying to Azure |
|||
|
|||
Microsoft has a good document on how to deploy your ASP.NET Core web app to Azure App Service. We recommend you to read this document https://docs.microsoft.com/en-us/azure/app-service/app-service-web-get-started-dotnet. |
|||
|
|||
- #### Running the Application From Command Line |
|||
|
|||
Alternatively you can run the application from command line, navigate to `VoloDocs\Web` folder and run `VoloDocs.Web.exe` for Windows or `VoloDocs.Web` for MacOS / Linux. |
|||
|
|||
- ### First Run |
|||
|
|||
To start the website, navigate to your address (as configured in the previous section). |
|||
|
|||
When you first open the website, you need to create a project. |
|||
|
|||
#### Creating a Project |
|||
|
|||
Go to the following address to create project |
|||
|
|||
- `http://<yourwebsite>/Account/Login?returnUrl=/Docs/Admin/Projects` |
|||
|
|||
##### Default credentials |
|||
|
|||
To login the admin side, use the following credentials: |
|||
|
|||
* **Username**: `admin` |
|||
|
|||
* **Password**: `1q2w3E*` |
|||
|
|||
##### An example project definition |
|||
|
|||
Here's a sample project information that uses GitHub source. |
|||
|
|||
We will configure the VoloDocs to show ABP Framework's documentation that's stored in GitHub. |
|||
|
|||
Here's the link to ABP Framework GitHub docs folder: |
|||
|
|||
https://github.com/abpframework/abp/tree/master/docs/en |
|||
|
|||
|
|||
|
|||
* **Name**: `ABP Framework` |
|||
|
|||
* **Short name**: `abp` |
|||
|
|||
* **Format**: `markdown` |
|||
|
|||
* **Default document name**: `Index` |
|||
|
|||
* **Navigation document name**: `docs-nav.json` ([see the sample navigation](https://github.com/abpframework/abp/blob/master/docs/en/docs-nav.json)) |
|||
|
|||
* **Minimum version**: *leave empty* *(hides the previous versions)* |
|||
|
|||
* **Main web site URL**: `/` |
|||
|
|||
* **Latest version branch name**: leave empty () |
|||
|
|||
* **GitHub root URL**: `https://github.com/abpframework/abp/tree/{version}/docs/en/` |
|||
|
|||
* **GitHub access token**: [see how to retrieve GitHub access token](#retrieving-github-access-token) |
|||
|
|||
* **GitHub user agent**: [see how to learn your GitHub username](#learn-your-github-username) |
|||
|
|||
 |
|||
|
|||
##### Retrieving GitHub Access Token |
|||
|
|||
To create a personal access token in GitHub, you need to visit the **Settings** of the user account and under **Developer settings** you will find **Personal access tokens**. Select **Generate new token**, enter in a name as the Token description and enable the repo checkbox. Alternatively, to enter generate new token, browse to https://github.com/settings/tokens/new. |
|||
|
|||
###### Generate Token for Public Repositories |
|||
|
|||
To access public repositories, check `public_repo` under the `repo` section. This will enable VoloDocs to access your public GitHub repositories. Click `Generate Token` button on the bottom of the page. |
|||
|
|||
 |
|||
|
|||
###### Generate Token for Private Repositories |
|||
|
|||
To access public repositories, check all items under the `repo` section. This will enable VoloDocs to access your private GitHub repositories. Click `Generate Token` button on the bottom of the page. |
|||
|
|||
 |
|||
|
|||
###### Learn Your GitHub Username |
|||
|
|||
To learn your GitHub username, click on your profile picture on the top-right corner of the GitHub page. You will see your username right after the text "Signed in as ..." |
|||
|
|||
 |
|||
|
|||
|
|||
|
|||
After you save the project, go to root website address and you will see your documentation. |
|||
|
|||
`http://<yourwebsite>/documents` |
|||
|
|||
### Any Issues? |
|||
|
|||
If you encounter any problem or issues about installation, usage or report a bug, follow the link: |
|||
|
|||
https://github.com/abpframework/abp/issues/new |
|||
|
|||
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 153 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 144 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
@ -0,0 +1,25 @@ |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Authentication.JwtBearer; |
|||
|
|||
namespace Microsoft.AspNetCore.Builder |
|||
{ |
|||
public static class ApplicationBuilderAbpJwtTokenMiddlewareExtension |
|||
{ |
|||
public static IApplicationBuilder UseJwtTokenMiddleware(this IApplicationBuilder app, string schema = JwtBearerDefaults.AuthenticationScheme) |
|||
{ |
|||
return app.Use(async (ctx, next) => |
|||
{ |
|||
if (ctx.User.Identity?.IsAuthenticated != true) |
|||
{ |
|||
var result = await ctx.AuthenticateAsync(schema); |
|||
if (result.Succeeded && result.Principal != null) |
|||
{ |
|||
ctx.User = result.Principal; |
|||
} |
|||
} |
|||
|
|||
await next(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.AspNetCore.Authentication.JwtBearer</AssemblyName> |
|||
<PackageId>Volo.Abp.AspNetCore.Authentication.JwtBearer</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.2.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Security; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Authentication.JwtBearer |
|||
{ |
|||
[DependsOn(typeof(AbpSecurityModule))] |
|||
public class AbpAspNetCoreAuthenticationJwtBearerModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
|
|||
namespace Volo.Abp.Cli |
|||
{ |
|||
public class Program |
|||
{ |
|||
private static void Main(string[] args) |
|||
{ |
|||
Console.WriteLine("Welcome to ABP CLI..! This tool is in development. There is no functionality yet. So, bye bye... ;)"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>netcoreapp2.2</TargetFramework> |
|||
<PackAsTool>true</PackAsTool> |
|||
<ToolCommandName>abp</ToolCommandName> |
|||
</PropertyGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.FluentValidation</AssemblyName> |
|||
<PackageId>Volo.Abp.FluentValidation</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="FluentValidation" Version="8.2.3" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Validation\Volo.Abp.Validation.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,46 @@ |
|||
using System; |
|||
using FluentValidation; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.FluentValidation |
|||
{ |
|||
public class AbpFluentValidationConventionalRegistrar : DefaultConventionalRegistrar |
|||
{ |
|||
public override void AddType(IServiceCollection services, Type type) |
|||
{ |
|||
if (!typeof(IValidator).IsAssignableFrom(type)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var validatingType = GetFirstGenericArgumentOrNull(type, 1); |
|||
if (validatingType == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
services.AddTransient( |
|||
typeof(IValidator<>).MakeGenericType(validatingType), |
|||
type |
|||
); |
|||
} |
|||
|
|||
private static Type GetFirstGenericArgumentOrNull(Type type, int depth) |
|||
{ |
|||
const int maxFindDepth = 8; |
|||
|
|||
if (depth >= maxFindDepth) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
if (type.IsGenericType && type.GetGenericArguments().Length >= 1) |
|||
{ |
|||
return type.GetGenericArguments()[0]; |
|||
} |
|||
|
|||
return GetFirstGenericArgumentOrNull(type.BaseType, depth + 1); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace Volo.Abp.FluentValidation |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpValidationModule) |
|||
)] |
|||
public class AbpFluentValidationModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddConventionalRegistrar(new AbpFluentValidationConventionalRegistrar()); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpValidationOptions>(options => |
|||
{ |
|||
options.MethodValidationContributors.Add<FluentMethodInvocationValidator>(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using FluentValidation; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace Volo.Abp.FluentValidation |
|||
{ |
|||
public class FluentMethodInvocationValidator : IMethodInvocationValidator, ITransientDependency |
|||
{ |
|||
private readonly IServiceProvider _serviceProvider; |
|||
|
|||
public FluentMethodInvocationValidator( |
|||
IServiceProvider serviceProvider) |
|||
{ |
|||
_serviceProvider = serviceProvider; |
|||
} |
|||
|
|||
public void Validate(MethodInvocationValidationContext context) |
|||
{ |
|||
var validationResult = new AbpValidationResult(); |
|||
|
|||
foreach (var parameterValue in context.ParameterValues) |
|||
{ |
|||
var serviceType = typeof(IValidator<>).MakeGenericType(parameterValue.GetType()); |
|||
var validator = _serviceProvider.GetService(serviceType) as IValidator; |
|||
if (validator == null) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
var result = validator.Validate(parameterValue); |
|||
if (!result.IsValid) |
|||
{ |
|||
validationResult.Errors.AddRange( |
|||
result.Errors.Select( |
|||
error => |
|||
new ValidationResult(error.ErrorMessage) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
if (validationResult.Errors.Any()) |
|||
{ |
|||
//TODO: How to localize messages?
|
|||
throw new AbpValidationException( |
|||
"Method arguments are not valid! See ValidationErrors for details.", |
|||
context.Errors |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,7 +1,7 @@ |
|||
namespace Volo.Abp.Validation |
|||
namespace Volo.Abp.Validation |
|||
{ |
|||
public interface IMethodInvocationValidator |
|||
{ |
|||
void Validate(MethodInvocationValidationContext context); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,3 @@ |
|||
# Volo.Abp |
|||
|
|||
This package is a name holder. It just references to the `Volo.Abp.Core` package. |
|||
@ -0,0 +1,19 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp</AssemblyName> |
|||
<PackageId>Volo.Abp</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,21 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp2.2</TargetFramework> |
|||
<AssemblyName>Volo.Abp.FluentValidation.Tests</AssemblyName> |
|||
<PackageId>Volo.Abp.FluentValidation.Tests</PackageId> |
|||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
|||
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.FluentValidation\Volo.Abp.FluentValidation.csproj" /> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,206 @@ |
|||
using System.Threading.Tasks; |
|||
using FluentValidation; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Shouldly; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Validation; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.FluentValidation |
|||
{ |
|||
public class ApplicationService_FluentValidation_Tests : AbpIntegratedTest<ApplicationService_FluentValidation_Tests.TestModule> |
|||
{ |
|||
private readonly IMyAppService _myAppService; |
|||
|
|||
public ApplicationService_FluentValidation_Tests() |
|||
{ |
|||
_myAppService = ServiceProvider.GetRequiredService<IMyAppService>(); |
|||
} |
|||
|
|||
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
|||
{ |
|||
options.UseAutofac(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Work_Proper_With_Right_Inputs() |
|||
{ |
|||
// MyStringValue should be aaa, MyStringValue2 should be bbb. MyStringValue3 should be ccc
|
|||
var output = _myAppService.MyMethod(new MyMethodInput |
|||
{ |
|||
MyStringValue = "aaa", |
|||
MyMethodInput2 = new MyMethodInput2 |
|||
{ |
|||
MyStringValue2 = "bbb" |
|||
}, |
|||
MyMethodInput3 = new MyMethodInput3 |
|||
{ |
|||
MyStringValue3 = "ccc" |
|||
} |
|||
}); |
|||
output.ShouldBe("aaabbbccc"); |
|||
|
|||
var asyncOutput = await _myAppService.MyMethodAsync(new MyMethodInput |
|||
{ |
|||
MyStringValue = "aaa", |
|||
MyMethodInput2 = new MyMethodInput2 |
|||
{ |
|||
MyStringValue2 = "bbb" |
|||
}, |
|||
MyMethodInput3 = new MyMethodInput3 |
|||
{ |
|||
MyStringValue3 = "ccc" |
|||
} |
|||
}); |
|||
|
|||
asyncOutput.ShouldBe("aaabbbccc"); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Not_Work_With_Wrong_Inputs() |
|||
{ |
|||
// MyStringValue should be aaa, MyStringValue2 should be bbb. MyStringValue3 should be ccc
|
|||
|
|||
Assert.Throws<AbpValidationException>(() => _myAppService.MyMethod(new MyMethodInput |
|||
{ |
|||
MyStringValue = "a", |
|||
MyMethodInput2 = new MyMethodInput2 |
|||
{ |
|||
MyStringValue2 = "b" |
|||
}, |
|||
MyMethodInput3 = new MyMethodInput3 |
|||
{ |
|||
MyStringValue3 = "c" |
|||
} |
|||
})); |
|||
|
|||
await Assert.ThrowsAsync<AbpValidationException>(async () => await _myAppService.MyMethodAsync( |
|||
new MyMethodInput |
|||
{ |
|||
MyStringValue = "a", |
|||
MyMethodInput2 = new MyMethodInput2 |
|||
{ |
|||
MyStringValue2 = "b" |
|||
}, |
|||
MyMethodInput3 = new MyMethodInput3 |
|||
{ |
|||
MyStringValue3 = "c" |
|||
} |
|||
})); |
|||
} |
|||
|
|||
[Fact] |
|||
public void NotValidateMyMethod_Test() |
|||
{ |
|||
var output = _myAppService.NotValidateMyMethod(new MyMethodInput4 |
|||
{ |
|||
MyStringValue4 = "444" |
|||
}); |
|||
|
|||
output.ShouldBe("444"); |
|||
} |
|||
|
|||
|
|||
[DependsOn(typeof(AbpAutofacModule))] |
|||
[DependsOn(typeof(AbpFluentValidationModule))] |
|||
public class TestModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.OnRegistred(onServiceRegistredContext => |
|||
{ |
|||
if (typeof(IMyAppService).IsAssignableFrom(onServiceRegistredContext.ImplementationType)) |
|||
{ |
|||
onServiceRegistredContext.Interceptors.TryAdd<ValidationInterceptor>(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddType<MyAppService>(); |
|||
} |
|||
} |
|||
|
|||
public interface IMyAppService |
|||
{ |
|||
string MyMethod(MyMethodInput input); |
|||
|
|||
Task<string> MyMethodAsync(MyMethodInput input); |
|||
|
|||
string NotValidateMyMethod(MyMethodInput4 input); |
|||
} |
|||
|
|||
public class MyAppService : IMyAppService, ITransientDependency |
|||
{ |
|||
public string MyMethod(MyMethodInput input) |
|||
{ |
|||
return input.MyStringValue + input.MyMethodInput2.MyStringValue2 + input.MyMethodInput3.MyStringValue3; |
|||
} |
|||
|
|||
public Task<string> MyMethodAsync(MyMethodInput input) |
|||
{ |
|||
return Task.FromResult(input.MyStringValue + input.MyMethodInput2.MyStringValue2 + |
|||
input.MyMethodInput3.MyStringValue3); |
|||
} |
|||
|
|||
public string NotValidateMyMethod(MyMethodInput4 input) |
|||
{ |
|||
return input.MyStringValue4; |
|||
} |
|||
} |
|||
|
|||
public class MyMethodInput |
|||
{ |
|||
public string MyStringValue { get; set; } |
|||
|
|||
public MyMethodInput2 MyMethodInput2 { get; set; } |
|||
|
|||
public MyMethodInput3 MyMethodInput3 { get; set; } |
|||
} |
|||
|
|||
public class MyMethodInput2 |
|||
{ |
|||
public string MyStringValue2 { get; set; } |
|||
} |
|||
|
|||
public class MyMethodInput3 |
|||
{ |
|||
|
|||
public string MyStringValue3 { get; set; } |
|||
} |
|||
|
|||
public class MyMethodInput4 |
|||
{ |
|||
public string MyStringValue4 { get; set; } |
|||
} |
|||
|
|||
public class MyMethodInputValidator : AbstractValidator<MyMethodInput> |
|||
{ |
|||
public MyMethodInputValidator() |
|||
{ |
|||
RuleFor(x => x.MyStringValue).Equal("aaa"); |
|||
RuleFor(x => x.MyMethodInput2.MyStringValue2).Equal("bbb"); |
|||
RuleFor(customer => customer.MyMethodInput3).SetValidator(new MyMethodInput3Validator()); |
|||
} |
|||
} |
|||
|
|||
public class MethodInputBaseValidator : AbstractValidator<MyMethodInput3> |
|||
{ |
|||
public MethodInputBaseValidator() |
|||
{ |
|||
RuleFor(x => x.MyStringValue3).NotNull(); |
|||
} |
|||
} |
|||
|
|||
public class MyMethodInput3Validator : MethodInputBaseValidator |
|||
{ |
|||
public MyMethodInput3Validator() |
|||
{ |
|||
RuleFor(x => x.MyStringValue3).Equal("ccc"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
.vs-blog .hero-section .hero-article-img { |
|||
min-height: 480px; |
|||
background: center center no-repeat; |
|||
background-size: cover; } |
|||
@ -0,0 +1 @@ |
|||
.vs-blog .hero-section .hero-article-img{min-height:480px;background:center center no-repeat;background-size:cover;} |
|||
@ -0,0 +1,10 @@ |
|||
.vs-blog { |
|||
.hero-section { |
|||
.hero-article-img { |
|||
min-height: 480px; |
|||
background: center center no-repeat; |
|||
background-size: cover; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -1 +1 @@ |
|||
.hero-section{padding:0;}.hero-section .hero-articles{position:relative;overflow:hidden;}.hero-section .hero-articles .hero-content{position:absolute;left:12%;right:12%;bottom:80px;z-index:4;text-align:center;}.hero-section .hero-articles .hero-content h2{margin-top:0;font-size:2.5em;font-weight:bold;}.hero-section .hero-articles .hero-content a{color:#fff;text-shadow:0 0 20px rgba(0,0,0,.5);}.hero-section .hero-articles .hero-content p{color:#fff;}.hero-section .hero-articles .tags .tag{background:rgba(208,208,208,.3);color:#fff !important;}.hero-section .hero-articles .tags .tag:hover{background:#fff;color:#000 !important;}.hero-section .hero-articles .article-owner{text-align:center;position:relative;z-index:12;}.hero-section .hero-articles .article-owner .article-infos{color:#000;}.hero-section .hero-articles .article-owner .article-infos a{color:#000;}.hero-section .hero-articles .article-owner .article-infos .seperator{margin:0 4px;color:rgba(255,255,255,.2);}.hero-section .hero-articles .article-owner .article-infos img.article-avatar{width:64px;margin:-25px 10px 0 0;border:3px solid #fff;display:inline-block;border-radius:50%;}.hero-section .hero-articles .img-container{background:#000;}.hero-section .hero-articles .img-container img{filter:grayscale(10%);}.hero-section .hero-articles .img-container::after{content:"";display:block;position:absolute;z-index:1;bottom:0;width:100%;top:1% !important;background:linear-gradient(to bottom,transparent 0,rgba(0,0,0,.91) 89%,rgba(0,0,0,.93) 93%) !important;transition:.2s all ease-in-out;opacity:.9;}.hero-section .hero-articles:hover .img-container::after{opacity:1;}.article-owner .article-infos{color:#000;}.article-owner .article-infos a{color:rgba(0,0,0,.6);}.article-owner .article-infos .seperator{margin:0 4px;color:rgba(0,0,0,.2);}.article-owner .article-infos img.article-avatar{width:30px;margin:-1px 4px 0 0;display:inline-block;border-radius:50%;}.card-articles .card-content{padding:10px 0 10px;}.card-articles .card-content h3{margin:10px 0;}.card-articles .card-content h3 a{font-weight:700;}.card-articles .article-owner{text-align:left;}.card-articles .article-owner .article-infos{color:#000;}.card-articles .article-owner .article-infos a{color:rgba(0,0,0,.6);}.card-articles .article-owner .article-infos .seperator{margin:0 4px;color:rgba(0,0,0,.2);}.card-articles .article-owner .article-infos img.article-avatar{width:30px;margin:-1px 4px 0 0;display:inline-block;border-radius:50%;}.article-owner{font-size:.85em;}.user-link-icons{position:absolute;right:18px;top:15px;z-index:3;}.user-link-icons a{display:inline-block;color:#eee;margin-left:12px;font-size:1.25em;}.user-link-icons a:hover{color:#fff;}.tags .tag{display:inline-block;padding:2px 8px;background:rgba(208,208,208,.3);border-radius:30px;margin:0 1px 3px 0;color:#b1b1b1 !important;font-size:.7em;line-height:1.6em;text-transform:uppercase;}.tags .tag:hover{background:#000;color:#fff !important;}.popular-tags a{display:block;font-size:.9em;}.popular-tags a span{float:right;opacity:.3;font-size:.9em;}.img-container{position:relative;overflow:hidden;border-radius:4px;} |
|||
.hero-section{padding:0;}.hero-section .hero-articles{position:relative;overflow:hidden;}.hero-section .hero-articles .hero-content{position:absolute;left:12%;right:12%;bottom:80px;z-index:4;text-align:center;}.hero-section .hero-articles .hero-content h2{margin-top:0;font-size:2.5em;font-weight:bold;}.hero-section .hero-articles .hero-content a{color:#fff;text-shadow:0 0 20px rgba(0,0,0,.5);}.hero-section .hero-articles .hero-content p{color:#fff;}.hero-section .hero-articles .tags .tag{background:rgba(208,208,208,.3);color:#fff !important;}.hero-section .hero-articles .tags .tag:hover{background:#fff;color:#000 !important;}.hero-section .hero-articles .article-owner{text-align:center;position:relative;z-index:12;}.hero-section .hero-articles .article-owner .article-infos{color:#000;}.hero-section .hero-articles .article-owner .article-infos a{color:#000;}.hero-section .hero-articles .article-owner .article-infos .seperator{margin:0 4px;color:rgba(255,255,255,.2);}.hero-section .hero-articles .article-owner .article-infos img.article-avatar{width:64px;margin:-25px 10px 0 0;border:3px solid #fff;display:inline-block;border-radius:50%;}.hero-section .hero-articles .img-container{min-height:320px;}.hero-section .hero-articles .img-container img{filter:grayscale(10%);}.hero-section .hero-articles .img-container::after{content:"";display:block;position:absolute;z-index:1;bottom:0;width:100%;top:1% !important;background:linear-gradient(to bottom,transparent 0,rgba(0,0,0,.75) 89%,rgba(0,0,0,.78) 93%) !important;transition:.2s all ease-in-out;opacity:.9;}.hero-section .hero-articles:hover .img-container::after{opacity:1;}.article-owner .article-infos{color:#000;}.article-owner .article-infos a{color:rgba(0,0,0,.6);}.article-owner .article-infos .seperator{margin:0 4px;color:rgba(0,0,0,.2);}.article-owner .article-infos img.article-avatar{width:30px;margin:-1px 4px 0 0;display:inline-block;border-radius:50%;}.card-articles .card-content{padding:10px 0 10px;}.card-articles .card-content h3{margin:10px 0;}.card-articles .card-content h3 a{font-weight:700;}.card-articles .article-owner{text-align:left;}.card-articles .article-owner .article-infos{color:#000;}.card-articles .article-owner .article-infos a{color:rgba(0,0,0,.6);}.card-articles .article-owner .article-infos .seperator{margin:0 4px;color:rgba(0,0,0,.2);}.card-articles .article-owner .article-infos img.article-avatar{width:30px;margin:-1px 4px 0 0;display:inline-block;border-radius:50%;}.article-owner{font-size:.85em;}.user-link-icons{position:absolute;right:18px;top:15px;z-index:3;}.user-link-icons a{display:inline-block;color:#eee;margin-left:12px;font-size:1.25em;}.user-link-icons a:hover{color:#fff;}.tags .tag{display:inline-block;padding:2px 8px;background:rgba(208,208,208,.3);border-radius:30px;margin:0 1px 3px 0;color:#b1b1b1 !important;font-size:.7em;line-height:1.6em;text-transform:uppercase;}.tags .tag:hover{background:#000;color:#fff !important;}.popular-tags a{display:block;font-size:.9em;}.popular-tags a span{float:right;opacity:.3;font-size:.9em;}.img-container{position:relative;overflow:hidden;border-radius:4px;background:#dcdcdc;} |
|||
File diff suppressed because one or more lines are too long
@ -1,4 +0,0 @@ |
|||
@page |
|||
@model Volo.DocsTestApp.Pages.IndexModel |
|||
<h3>Welcome to the Docs Demo!</h3> |
|||
<a href="/documents/">Go to documents...</a> |
|||
@ -1,16 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
|
|||
namespace Volo.DocsTestApp.Pages |
|||
{ |
|||
public class IndexModel : PageModel |
|||
{ |
|||
public void OnGet() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"ConnectionStrings": { |
|||
"SqlServer": "Server=localhost;Database=DocsTestApp;Trusted_Connection=True;MultipleActiveResultSets=true", |
|||
"MongoDb": "mongodb://localhost:27017|DocsTestApp" |
|||
} |
|||
} |
|||
@ -1,7 +1,7 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace Volo.DocsTestApp.EntityFrameworkCore.Migrations |
|||
namespace VoloDocs.EntityFrameworkCore.Migrations |
|||
{ |
|||
public partial class Initial20181225 : Migration |
|||
{ |
|||
@ -0,0 +1,13 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp; |
|||
|
|||
namespace VoloDocs.Migrator |
|||
{ |
|||
public static class AppExtensions |
|||
{ |
|||
public static T Resolve<T>(this IAbpApplicationWithInternalServiceProvider app) |
|||
{ |
|||
return (T)app.ServiceProvider.GetRequiredService<T>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1 @@ |
|||
@dotnet VoloDocs.Migrator.dll |
|||
@ -0,0 +1,94 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp; |
|||
using VoloDocs.EntityFrameworkCore; |
|||
|
|||
namespace VoloDocs.Migrator |
|||
{ |
|||
class Program |
|||
{ |
|||
private const string ScriptFile = "Script.txt"; |
|||
|
|||
static void Main(string[] args) |
|||
{ |
|||
Console.WriteLine("Initializing VoloDocs Migrator ... "); |
|||
|
|||
using (var app = AbpApplicationFactory.Create<VoloDocsMigratorModule>()) |
|||
{ |
|||
app.Initialize(); |
|||
|
|||
using (var dbContext = app.Resolve<VoloDocsDbContext>()) |
|||
{ |
|||
var connectionString = dbContext.Database.GetDbConnection().ConnectionString; |
|||
|
|||
Console.Clear(); |
|||
|
|||
if (args != null && args.Contains("-script")) |
|||
{ |
|||
GenerateMigrationScript(dbContext); |
|||
return; |
|||
} |
|||
|
|||
RunMigrations(connectionString, dbContext); |
|||
} |
|||
|
|||
Console.WriteLine("\n\nPress ENTER to exit..."); |
|||
Console.ReadLine(); |
|||
} |
|||
} |
|||
|
|||
private static void RunMigrations(string connectionString, VoloDocsDbContext dbContext) |
|||
{ |
|||
Console.Write("\nThis program updates an existing database or creates a new one if not exists.\n" + |
|||
"The following connection string will be used:\n\n" + |
|||
connectionString + "\n\n" + |
|||
"Are you sure you want to run the migration? (y/n) "); |
|||
|
|||
if (Console.ReadKey().Key == ConsoleKey.Y) |
|||
{ |
|||
Console.WriteLine("\n\nMigrating database..."); |
|||
|
|||
try |
|||
{ |
|||
dbContext.Database.Migrate(); |
|||
|
|||
Console.WriteLine("Migration completed."); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Console.WriteLine(ex.Message); |
|||
|
|||
while (ex.InnerException != null) |
|||
{ |
|||
ex = ex.InnerException; |
|||
Console.WriteLine(ex.Message); |
|||
} |
|||
|
|||
Console.Write("\nThere was problem while applying migrations. " + |
|||
"Do you want to create the migration script? (y/n) "); |
|||
|
|||
if (Console.ReadKey().Key == ConsoleKey.Y) |
|||
{ |
|||
GenerateMigrationScript(dbContext); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void GenerateMigrationScript(VoloDocsDbContext dbContext) |
|||
{ |
|||
if (File.Exists(ScriptFile)) |
|||
{ |
|||
File.Delete(ScriptFile); |
|||
} |
|||
|
|||
Console.Write("\nGenerating migration scripts..."); |
|||
|
|||
File.WriteAllText(ScriptFile, dbContext.Database.GenerateCreateScript()); |
|||
|
|||
Console.Write("\nMigration script has been created to Script.txt file"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>netcoreapp2.2</TargetFramework> |
|||
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Core\Volo.Abp.Core.csproj" /> |
|||
<ProjectReference Include="..\VoloDocs.EntityFrameworkCore\VoloDocs.EntityFrameworkCore.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Content Include="appsettings.json"> |
|||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> |
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|||
</Content> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Update="Migrate.bat"> |
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|||
</None> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,29 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.Abp.Modularity; |
|||
using VoloDocs.EntityFrameworkCore; |
|||
|
|||
namespace VoloDocs.Migrator |
|||
{ |
|||
[DependsOn(typeof(VoloDocsEntityFrameworkCoreModule))] |
|||
public class VoloDocsMigratorModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
context.Services.AddAbpDbContext<VoloDocsDbContext>(); |
|||
|
|||
Configure<DbConnectionOptions>(options => |
|||
{ |
|||
options.ConnectionStrings.Default = configuration["ConnectionString"]; |
|||
}); |
|||
|
|||
Configure<AbpDbContextOptions>(options => |
|||
{ |
|||
options.UseSqlServer(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
{ |
|||
"ConnectionString": "Server=localhost;Database=VoloDocs;Trusted_Connection=True;MultipleActiveResultSets=true" |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components; |
|||
using Volo.Abp.Configuration; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace VoloDocs.Web.Branding |
|||
{ |
|||
[Dependency(ReplaceServices = true)] |
|||
public class VoloDocsBrandingProvider : DefaultBrandingProvider |
|||
{ |
|||
public VoloDocsBrandingProvider(IConfigurationAccessor configurationAccessor) |
|||
{ |
|||
var configuration = configurationAccessor.Configuration; |
|||
|
|||
if (configuration["Title"] != null) |
|||
{ |
|||
AppName = configuration["Title"]; |
|||
} |
|||
|
|||
if (configuration["LogoUrl"] != null) |
|||
{ |
|||
LogoUrl = configuration["LogoUrl"]; |
|||
} |
|||
} |
|||
|
|||
public override string AppName { get; } |
|||
|
|||
public override string LogoUrl { get; } |
|||
} |
|||
} |
|||
@ -1,6 +1,6 @@ |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace Volo.DocsTestApp.Controllers |
|||
namespace VoloDocs.Web.Controllers |
|||
{ |
|||
public class HomeController : AbpController |
|||
{ |
|||
@ -0,0 +1,9 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"WelcomeVoloDocs": "Welcome to the VoloDocs!", |
|||
"NoProjectWarning": "There`s no defined project yet!", |
|||
"CreateYourFirstProject": "Click here to start your first project", |
|||
"NoProject": "No project!" |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"WelcomeVoloDocs": "VoloDocs Hoşgeldiniz!", |
|||
"NoProjectWarning": "Henüz bir proje yok!", |
|||
"CreateYourFirstProject": "İlk projenizi oluşturmak için tıklayın", |
|||
"NoProject": "Proje yok!" |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
@page |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Docs.Localization |
|||
@model VoloDocs.Web.Pages.ErrorModel |
|||
@inject IHtmlLocalizer<DocsResource> L |
|||
@{ |
|||
<div class="text-center"> |
|||
<pre> |
|||
@Model.ErrorMessage |
|||
</pre> |
|||
|
|||
<a href="/" class="btn btn-outline-primary">@L["BackToWebsite"]</a> |
|||
</div> |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
@page |
|||
|
|||
@using System.Linq |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Docs |
|||
@using Volo.Docs.Localization |
|||
@using Volo.Docs.Pages.Documents |
|||
|
|||
@model VoloDocs.Web.Pages.IndexModel |
|||
@inject IHtmlLocalizer<DocsResource> L |
|||
|
|||
@section styles { |
|||
<abp-style-bundle name="@typeof(IndexModel).FullName"> |
|||
<abp-style src="/Pages/Documents/Shared/Styles/vs.css" /> |
|||
<abp-style src="/assets/fa/css/font-awesome.min.css" /> |
|||
</abp-style-bundle> |
|||
} |
|||
|
|||
<div class="p-5"> |
|||
|
|||
<h1 class="text-center mb-5"> |
|||
@L["WelcomeVoloDocs"] |
|||
</h1> |
|||
|
|||
@if (!Model.Projects.Any()) |
|||
{ |
|||
<div class="d-flex justify-content-center"> |
|||
<div class="alert alert-secondary col-md-6 text-center" role="alert"> |
|||
<p>@L["NoProjectWarning"]</p> |
|||
<hr /> |
|||
<a href="/Docs/Admin/Projects">@L["CreateYourFirstProject"] <i class="fa fa-arrow-circle-right"></i></a> |
|||
</div> |
|||
</div> |
|||
} |
|||
else if (Model.Projects.Count > 1) |
|||
{ |
|||
<h2>@L["Projects"]</h2> |
|||
<p> |
|||
<ul style="list-style-type: upper-roman;"> |
|||
@foreach (var project in Model.Projects) |
|||
{ |
|||
<li> |
|||
<h3> |
|||
<a asp-page="./Project/Index" |
|||
asp-route-projectName="@project.ShortName" |
|||
asp-route-version="@DocsAppConsts.Latest"> |
|||
@project.Name |
|||
</a> |
|||
</h3> |
|||
</li> |
|||
} |
|||
</ul> |
|||
</p> |
|||
} |
|||
|
|||
</div> |
|||
@ -0,0 +1,38 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
using Volo.Docs; |
|||
using Volo.Docs.Projects; |
|||
|
|||
namespace VoloDocs.Web.Pages |
|||
{ |
|||
public class IndexModel : PageModel |
|||
{ |
|||
public IReadOnlyList<ProjectDto> Projects { get; set; } |
|||
|
|||
private readonly IProjectAppService _projectAppService; |
|||
|
|||
public IndexModel(IProjectAppService projectAppService) |
|||
{ |
|||
_projectAppService = projectAppService; |
|||
} |
|||
|
|||
public async Task<IActionResult> OnGet() |
|||
{ |
|||
Projects = (await _projectAppService.GetListAsync()).Items; |
|||
|
|||
if (Projects.Count == 1) |
|||
{ |
|||
return RedirectToPage("./Documents/Project/Index", new |
|||
{ |
|||
projectName = Projects[0].ShortName, |
|||
version = DocsAppConsts.Latest, |
|||
documentName = Projects[0].DefaultDocumentName |
|||
}); |
|||
} |
|||
|
|||
return Page(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp.AspNetCore.Uow; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Docs; |
|||
|
|||
namespace VoloDocs.Web.Utils |
|||
{ |
|||
public class GlobalExceptionHandlerMiddleware |
|||
{ |
|||
private readonly RequestDelegate _next; |
|||
private readonly ILogger<AbpUnitOfWorkMiddleware> _logger; |
|||
|
|||
public GlobalExceptionHandlerMiddleware(RequestDelegate next, ILogger<AbpUnitOfWorkMiddleware> logger) |
|||
{ |
|||
_logger = logger; |
|||
_next = next; |
|||
} |
|||
|
|||
public async Task Invoke(HttpContext httpContext) |
|||
{ |
|||
try |
|||
{ |
|||
await _next(httpContext); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError("Handled a global exception: " + ex.Message, ex); |
|||
|
|||
if (ex.Message.StartsWith("404 error") || |
|||
ex is EntityNotFoundException || |
|||
ex is DocumentNotFoundException) |
|||
{ |
|||
httpContext.Response.Redirect("/error/404"); |
|||
} |
|||
else |
|||
{ |
|||
httpContext.Response.Redirect("/error/500"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
{ |
|||
"ConnectionString": "Server=localhost;Database=VoloDocs;Trusted_Connection=True;MultipleActiveResultSets=true", |
|||
"Title": "VoloDocs", |
|||
"LogoUrl": "/assets/images/Logo.png" |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue