Browse Source

feat(mvc): 增加包装器模块,可对控制器、异常结果进行包装

pull/406/head
cKey 4 years ago
parent
commit
7b47e901d6
  1. 33
      aspnet-core/LINGYUN.MicroService.Common.sln
  2. 14
      aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN.Abp.Wrapper.csproj
  3. 9
      aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/AbpWrapperModule.cs
  4. 13
      aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/IgnoreWrapResultAttribute.cs
  5. 25
      aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/WrapResult.cs
  6. 49
      aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/WrapResult`T.cs
  7. 28
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN.Abp.AspNetCore.Mvc.Wrapper.csproj
  8. 65
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs
  9. 70
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperOptions.cs
  10. 7
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpHttpWrapConsts.cs
  11. 81
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs
  12. 82
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs
  13. 37
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Filters/AbpWrapResultFilter.cs
  14. 13
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/IWrapResultChecker.cs
  15. 9
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Localization/AbpMvcWrapperResource.cs
  16. 6
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Localization/Resources/en.json
  17. 6
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Localization/Resources/zh-Hans.json
  18. 157
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs
  19. 38
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/ActionResultWrapperFactory.cs
  20. 28
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/EmptyActionResultWrapper.cs
  21. 9
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/IActionResultWrapper.cs
  22. 10
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/IActionResultWrapperFactory.cs
  23. 40
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/JsonActionResultWrapper.cs
  24. 12
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/NullActionResultWrapper.cs
  25. 51
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/ObjectActionResultWrapper.cs
  26. 28
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/Microsoft/AspNetCore/Mvc/ActionContextExtensions.cs
  27. 37
      aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/README.md
  28. 2
      aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/Properties/launchSettings.json
  29. 39
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN.Abp.AspNetCore.Mvc.Tests.csproj
  30. 32
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestBase.cs
  31. 144
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
  32. 15
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/GlobalFeatures/AbpAspNetCoreMvcTestFeatures.cs
  33. 6
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Localization/MvcTestResource.cs
  34. 6
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/en.json
  35. 6
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/zh-Hans.json
  36. 28
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/DontWrapResultController.cs
  37. 8
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/HasDbException.cs
  38. 16
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/TestResultObject.cs
  39. 78
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/WrapResultController.cs
  40. 93
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/WrapResultController_Tests.cs
  41. 20
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Startup.cs
  42. 27
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/Properties/launchSettings.json
  43. 25
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Tests/LINGYUN.Abp.AspNetCore.Tests.csproj
  44. 49
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Tests/LINGYUN/Abp/AspNetCore/AbpAspNetCoreTestBase.cs
  45. 38
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Tests/LINGYUN/Abp/AspNetCore/AbpAspNetCoreTestModule.cs
  46. 20
      aspnet-core/tests/LINGYUN.Abp.AspNetCore.Tests/LINGYUN/Abp/AspNetCore/Startup.cs

33
aspnet-core/LINGYUN.MicroService.Common.sln

@ -192,7 +192,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.DataProtection.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EntityFrameworkCore.Tests", "tests\LINGYUN.Abp.EntityFrameworkCore.Tests\LINGYUN.Abp.EntityFrameworkCore.Tests.csproj", "{2F556889-006C-4A9C-8CA3-E31200C06FC9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Dapr", "modules\dapr\LINGYUN.Abp.Dapr\LINGYUN.Abp.Dapr.csproj", "{73C9A7E7-846D-49E2-B223-E705D6C48BE7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Dapr", "modules\dapr\LINGYUN.Abp.Dapr\LINGYUN.Abp.Dapr.csproj", "{73C9A7E7-846D-49E2-B223-E705D6C48BE7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Wrapper", "modules\common\LINGYUN.Abp.Wrapper\LINGYUN.Abp.Wrapper.csproj", "{328B0863-23BE-43FD-98DD-FF0C92D5BEF0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mvc", "mvc", "{F55B987D-1DFF-4EB0-9949-8A7136A7B689}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Mvc.Wrapper", "modules\mvc\LINGYUN.Abp.AspNetCore.Mvc.Wrapper\LINGYUN.Abp.AspNetCore.Mvc.Wrapper.csproj", "{D72748AF-2CC8-4B5B-9710-ECDE5D812D7F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Tests", "tests\LINGYUN.Abp.AspNetCore.Tests\LINGYUN.Abp.AspNetCore.Tests.csproj", "{BD4165DB-F8A4-4715-A05A-CC08F6A18D67}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Mvc.Tests", "tests\LINGYUN.Abp.AspNetCore.Mvc.Tests\LINGYUN.Abp.AspNetCore.Mvc.Tests.csproj", "{AE5E6DE8-FC02-4633-BA49-C4B8ABADB502}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -504,6 +514,22 @@ Global
{73C9A7E7-846D-49E2-B223-E705D6C48BE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{73C9A7E7-846D-49E2-B223-E705D6C48BE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{73C9A7E7-846D-49E2-B223-E705D6C48BE7}.Release|Any CPU.Build.0 = Release|Any CPU
{328B0863-23BE-43FD-98DD-FF0C92D5BEF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{328B0863-23BE-43FD-98DD-FF0C92D5BEF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{328B0863-23BE-43FD-98DD-FF0C92D5BEF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{328B0863-23BE-43FD-98DD-FF0C92D5BEF0}.Release|Any CPU.Build.0 = Release|Any CPU
{D72748AF-2CC8-4B5B-9710-ECDE5D812D7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D72748AF-2CC8-4B5B-9710-ECDE5D812D7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D72748AF-2CC8-4B5B-9710-ECDE5D812D7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D72748AF-2CC8-4B5B-9710-ECDE5D812D7F}.Release|Any CPU.Build.0 = Release|Any CPU
{BD4165DB-F8A4-4715-A05A-CC08F6A18D67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD4165DB-F8A4-4715-A05A-CC08F6A18D67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD4165DB-F8A4-4715-A05A-CC08F6A18D67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD4165DB-F8A4-4715-A05A-CC08F6A18D67}.Release|Any CPU.Build.0 = Release|Any CPU
{AE5E6DE8-FC02-4633-BA49-C4B8ABADB502}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE5E6DE8-FC02-4633-BA49-C4B8ABADB502}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE5E6DE8-FC02-4633-BA49-C4B8ABADB502}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE5E6DE8-FC02-4633-BA49-C4B8ABADB502}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -601,6 +627,11 @@ Global
{FBE7D8CB-1D99-4342-A953-B9AB46E0B14D} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
{2F556889-006C-4A9C-8CA3-E31200C06FC9} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
{73C9A7E7-846D-49E2-B223-E705D6C48BE7} = {7FDFB22F-1BFF-4E05-9427-78B7A8461D50}
{328B0863-23BE-43FD-98DD-FF0C92D5BEF0} = {086BE5BE-8594-4DA7-8819-935FEF76DABD}
{F55B987D-1DFF-4EB0-9949-8A7136A7B689} = {02EA4E78-5891-43BC-944F-3E52FEE032E4}
{D72748AF-2CC8-4B5B-9710-ECDE5D812D7F} = {F55B987D-1DFF-4EB0-9949-8A7136A7B689}
{BD4165DB-F8A4-4715-A05A-CC08F6A18D67} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
{AE5E6DE8-FC02-4633-BA49-C4B8ABADB502} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {06C707C6-02C0-411A-AD3B-2D0E13787CB8}

14
aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN.Abp.Wrapper.csproj

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Core" Version="4.4.0" />
</ItemGroup>
</Project>

9
aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/AbpWrapperModule.cs

@ -0,0 +1,9 @@
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Wrapper
{
public class AbpWrapperModule: AbpModule
{
}
}

13
aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/IgnoreWrapResultAttribute.cs

@ -0,0 +1,13 @@
using System;
namespace LINGYUN.Abp.Wrapper
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class IgnoreWrapResultAttribute : Attribute
{
public IgnoreWrapResultAttribute()
{
}
}
}

25
aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/WrapResult.cs

@ -0,0 +1,25 @@
using System;
namespace LINGYUN.Abp.Wrapper
{
[Serializable]
public class WrapResult: WrapResult<object>
{
public WrapResult() { }
public WrapResult(
string code,
string message,
string details = null)
: base(code, message, details)
{
}
public WrapResult(
string code,
object result,
string message = "OK")
: base(code, result, message)
{
}
}
}

49
aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/WrapResult`T.cs

@ -0,0 +1,49 @@
using System;
namespace LINGYUN.Abp.Wrapper
{
/// <summary>
/// 返回值包装结构
/// </summary>
/// <typeparam name="TResult"></typeparam>
[Serializable]
public class WrapResult<TResult>
{
/// <summary>
/// 错误代码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 错误提示消息
/// </summary>
public string Message { get; set; }
/// <summary>
/// 补充消息
/// </summary>
public string Details { get; set; }
/// <summary>
/// 返回值
/// </summary>
public TResult Result { get; set; }
public WrapResult() { }
public WrapResult(
string code,
string message,
string details = null)
{
Code = code;
Message = message;
Details = details;
}
public WrapResult(
string code,
TResult result,
string message = "OK")
{
Code = code;
Result = result;
Message = message;
}
}
}

28
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN.Abp.AspNetCore.Mvc.Wrapper.csproj

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\AspNetCore\Mvc\Wrapper\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\AspNetCore\Mvc\Wrapper\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\AspNetCore\Mvc\Wrapper\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\AspNetCore\Mvc\Wrapper\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\LINGYUN.Abp.Wrapper\LINGYUN.Abp.Wrapper.csproj" />
</ItemGroup>
</Project>

65
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs

@ -0,0 +1,65 @@
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Filters;
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Localization;
using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ApiExploring;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.AspNetCore.Mvc.ProxyScripting;
using Volo.Abp.Http.Modeling;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper
{
[DependsOn(
typeof(AbpWrapperModule),
typeof(AbpAspNetCoreMvcModule))]
public class AbpAspNetCoreMvcWrapperModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAspNetCoreMvcWrapperModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AbpMvcWrapperResource>("en")
.AddVirtualJson("/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Localization/Resources");
});
Configure<MvcOptions>(mvcOptions =>
{
// Wrap Result Filter
mvcOptions.Filters.AddService(typeof(AbpWrapResultFilter));
});
Configure<AbpAspNetCoreMvcWrapperOptions>(options =>
{
// 即使重写端点也不包装返回结果
// api/abp/api-definition
options.IgnoreReturnTypes.Add<ApplicationApiDescriptionModel>();
// api/abp/application-configuration
options.IgnoreReturnTypes.Add<ApplicationConfigurationDto>();
// Abp/ServiceProxyScript
options.IgnoreControllers.Add<AbpServiceProxyScriptController>();
// 官方模块不包装结果
options.IgnoreNamespaces.Add("Volo.Abp");
// 返回本地化的 404 错误消息
options.MessageWithEmptyResult = (serviceProvider) =>
{
var localizer = serviceProvider.GetRequiredService<IStringLocalizer<AbpMvcWrapperResource>>();
return localizer["Wrapper:NotFound"];
};
});
}
}
}

70
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperOptions.cs

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Net;
using Volo.Abp.Collections;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper
{
public class AbpAspNetCoreMvcWrapperOptions
{
/// <summary>
/// 是否启用包装器
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// 资源有效时返回代码
/// 默认:0
/// </summary>
public string CodeWithFound { get; set; }
/// <summary>
/// 资源为空时返回代码
/// 默认:404
/// </summary>
public Func<IServiceProvider, string> CodeWithEmptyResult { get; set; }
/// <summary>
/// 资源为空时返回错误消息
/// </summary>
public Func<IServiceProvider, string> MessageWithEmptyResult { get; set; }
/// <summary>
/// 包装后的返回状态码
/// 默认:200 HttpStatusCode.OK
/// </summary>
public HttpStatusCode HttpStatusCode { get; set; }
/// <summary>
/// 忽略Url开头类型
/// </summary>
public IList<string> IgnorePrefixUrls { get; }
/// <summary>
/// 忽略指定命名空间
/// </summary>
public IList<string> IgnoreNamespaces { get; }
/// <summary>
/// 忽略控制器
/// </summary>
public ITypeList IgnoreControllers { get; }
/// <summary>
/// 忽略返回值
/// </summary>
public ITypeList IgnoreReturnTypes { get; }
/// <summary>
/// 忽略异常
/// </summary>
public ITypeList<Exception> IgnoreExceptions { get; }
public AbpAspNetCoreMvcWrapperOptions()
{
CodeWithFound = "0";
HttpStatusCode = HttpStatusCode.OK;
IgnorePrefixUrls = new List<string>();
IgnoreNamespaces = new List<string>();
IgnoreControllers = new TypeList();
IgnoreReturnTypes = new TypeList();
IgnoreExceptions = new TypeList<Exception>();
CodeWithEmptyResult = (_) => "404";
MessageWithEmptyResult = (_) => "Not Found";
}
}
}

7
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpHttpWrapConsts.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper
{
public static class AbpHttpWrapConsts
{
public const string AbpWrapResult = "_AbpWrapResult";
}
}

81
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs

@ -0,0 +1,81 @@
using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.DependencyInjection;
using Volo.Abp.ExceptionHandling;
using Volo.Abp.Http;
using Volo.Abp.Json;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling
{
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(AbpExceptionPageFilter))]
public class AbpExceptionPageWrapResultFilter: AbpExceptionPageFilter, ITransientDependency
{
protected override bool ShouldHandleException(PageHandlerExecutingContext context)
{
if (!context.ActionDescriptor.CanWarpRsult())
{
return false;
}
return base.ShouldHandleException(context);
}
protected override async Task HandleAndWrapException(PageHandlerExecutedContext context)
{
var wrapResultChecker = context.GetRequiredService<IWrapResultChecker>();
if (!wrapResultChecker.WrapOnException(context))
{
await base.HandleAndWrapException(context);
return;
}
var wrapResultOptions = context.GetRequiredService<IOptions<AbpAspNetCoreMvcWrapperOptions>>().Value;
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients);
var logLevel = context.Exception.GetLogLevel();
var remoteServiceErrorInfoBuilder = new StringBuilder();
remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService<IJsonSerializer>().Serialize(remoteServiceErrorInfo, indented: true));
context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
var logger = context.GetService<ILogger<AbpExceptionPageWrapResultFilter>>(NullLogger<AbpExceptionPageWrapResultFilter>.Instance);
logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
logger.LogException(context.Exception, logLevel);
await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
// Warp Error Response
string errorCode = remoteServiceErrorInfo.Code;
if (context.Exception is IHasErrorCode exceptionWithErrorCode)
{
if (!exceptionWithErrorCode.Code.IsNullOrWhiteSpace() &&
exceptionWithErrorCode.Code.Contains(":"))
{
errorCode = exceptionWithErrorCode.Code.Split(':')[1];
}
else
{
errorCode = exceptionWithErrorCode.Code;
}
}
context.Result = new ObjectResult(new WrapResult(errorCode, remoteServiceErrorInfo.Message, remoteServiceErrorInfo.Details));
context.Exception = null; //Handled!
}
}
}

82
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs

@ -0,0 +1,82 @@
using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.DependencyInjection;
using Volo.Abp.ExceptionHandling;
using Volo.Abp.Http;
using Volo.Abp.Json;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling
{
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(AbpExceptionFilter))]
public class AbpExceptionWrapResultFilter : AbpExceptionFilter, ITransientDependency
{
protected override bool ShouldHandleException(ExceptionContext context)
{
var wrapResultChecker = context.GetRequiredService<IWrapResultChecker>();
if (!wrapResultChecker.WrapOnException(context))
{
return false;
}
return base.ShouldHandleException(context);
}
protected override async Task HandleAndWrapException(ExceptionContext context)
{
//TODO: Trigger an AbpExceptionHandled event or something like that.
var wrapResultOptions = context.GetRequiredService<IOptions<AbpAspNetCoreMvcWrapperOptions>>().Value;
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients);
var logLevel = context.Exception.GetLogLevel();
var remoteServiceErrorInfoBuilder = new StringBuilder();
remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService<IJsonSerializer>().Serialize(remoteServiceErrorInfo, indented: true));
var logger = context.GetService<ILogger<AbpExceptionWrapResultFilter>>(NullLogger<AbpExceptionWrapResultFilter>.Instance);
logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
logger.LogException(context.Exception, logLevel);
await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true");
context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
context.HttpContext.Response.StatusCode = (int)wrapResultOptions.HttpStatusCode;
// Warp Error Response
string errorCode = remoteServiceErrorInfo.Code;
if (context.Exception is IHasErrorCode exceptionWithErrorCode)
{
if (!exceptionWithErrorCode.Code.IsNullOrWhiteSpace() &&
exceptionWithErrorCode.Code.Contains(":"))
{
errorCode = exceptionWithErrorCode.Code.Split(':')[1];
}
else
{
errorCode = exceptionWithErrorCode.Code;
}
}
context.Result = new ObjectResult(new WrapResult(errorCode, remoteServiceErrorInfo.Message, remoteServiceErrorInfo.Details));
context.Exception = null; //Handled!
}
}
}

37
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Filters/AbpWrapResultFilter.cs

@ -0,0 +1,37 @@
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Filters
{
public class AbpWrapResultFilter : IAsyncResultFilter, ITransientDependency
{
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
if (ShouldWrapResult(context))
{
await HandleAndWrapResult(context);
}
await next();
}
protected virtual bool ShouldWrapResult(ResultExecutingContext context)
{
var wrapResultChecker = context.GetRequiredService<IWrapResultChecker>();
return wrapResultChecker.WrapOnExecution(context);
}
protected virtual Task HandleAndWrapResult(ResultExecutingContext context)
{
var actionResultWrapperFactory = context.GetRequiredService<IActionResultWrapperFactory>();
actionResultWrapperFactory.CreateFor(context).Wrap(context);
context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true");
return Task.CompletedTask;
}
}
}

13
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/IWrapResultChecker.cs

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc.Filters;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper
{
public interface IWrapResultChecker
{
bool WrapOnExecution(FilterContext context);
bool WrapOnException(ExceptionContext context);
bool WrapOnException(PageHandlerExecutedContext context);
}
}

9
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Localization/AbpMvcWrapperResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Localization
{
[LocalizationResourceName("AbpMvcWrapper")]
public class AbpMvcWrapperResource
{
}
}

6
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Localization/Resources/en.json

@ -0,0 +1,6 @@
{
"culture": "en",
"texts": {
"Wrapper:NotFound": "The requested resource was not found on the server."
}
}

6
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Localization/Resources/zh-Hans.json

@ -0,0 +1,6 @@
{
"culture": "zh-Hans",
"texts": {
"Wrapper:NotFound": "在服务器中没有找到请求的资源."
}
}

157
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs

@ -0,0 +1,157 @@
using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using System.Reflection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper
{
public class WrapResultChecker : IWrapResultChecker, ISingletonDependency
{
protected AbpAspNetCoreMvcWrapperOptions Options { get; }
public WrapResultChecker(IOptionsMonitor<AbpAspNetCoreMvcWrapperOptions> optionsMonitor)
{
Options = optionsMonitor.CurrentValue;
}
public bool WrapOnException(ExceptionContext context)
{
if (!CheckForBase(context))
{
return false;
}
return CheckForException(context.Exception);
}
public bool WrapOnException(PageHandlerExecutedContext context)
{
return CheckForException(context.Exception);
}
public bool WrapOnExecution(FilterContext context)
{
return CheckForBase(context);
}
protected virtual bool CheckForBase(FilterContext context)
{
if (context.ActionDescriptor is ControllerActionDescriptor descriptor)
{
if (!context.ActionDescriptor.HasObjectResult())
{
return false;
}
//if (!context.HttpContext.Request.CanAccept(MimeTypes.Application.Json))
//{
// return false;
//}
if (!CheckForUrl(context))
{
return false;
}
if (!CheckForNamespace(descriptor))
{
return false;
}
if (!CheckForController(descriptor))
{
return false;
}
if (!CheckForMethod(descriptor))
{
return false;
}
if (!CheckForReturnType(descriptor))
{
return false;
}
return true;
}
return false;
}
protected virtual bool CheckForUrl(FilterContext context)
{
if (!Options.IgnorePrefixUrls.Any())
{
return true;
}
var url = BuildUrl(context.HttpContext);
return !Options.IgnorePrefixUrls.Any(urlPrefix => urlPrefix.StartsWith(url));
}
protected virtual bool CheckForController(ControllerActionDescriptor controllerActionDescriptor)
{
if (controllerActionDescriptor.ControllerTypeInfo.IsDefined(typeof(IgnoreWrapResultAttribute), true))
{
return false;
}
return !Options.IgnoreControllers.Any(controller =>
controller.IsAssignableFrom(controllerActionDescriptor.ControllerTypeInfo));
}
protected virtual bool CheckForMethod(ControllerActionDescriptor controllerActionDescriptor)
{
return !controllerActionDescriptor.MethodInfo.IsDefined(typeof(IgnoreWrapResultAttribute), true);
}
protected virtual bool CheckForNamespace(ControllerActionDescriptor controllerActionDescriptor)
{
if (string.IsNullOrWhiteSpace(controllerActionDescriptor.ControllerTypeInfo.Namespace))
{
return true;
}
return !Options.IgnoreNamespaces.Any(nsp =>
controllerActionDescriptor.ControllerTypeInfo.Namespace.StartsWith(nsp));
}
protected virtual bool CheckForReturnType(ControllerActionDescriptor controllerActionDescriptor)
{
if (controllerActionDescriptor.MethodInfo.ReturnType.IsDefined(typeof(IgnoreWrapResultAttribute), true))
{
return false;
}
return !Options.IgnoreReturnTypes.Any(type =>
controllerActionDescriptor.MethodInfo.ReturnType.IsAssignableFrom(type));
}
protected virtual bool CheckForException(Exception exception)
{
return !Options.IgnoreExceptions.Any(ex => ex.IsAssignableFrom(exception.GetType()));
}
protected virtual string BuildUrl(HttpContext httpContext)
{
//TODO: Add options to include/exclude query, schema and host
var uriBuilder = new UriBuilder();
uriBuilder.Scheme = httpContext.Request.Scheme;
uriBuilder.Host = httpContext.Request.Host.Host;
uriBuilder.Path = httpContext.Request.Path.ToString();
uriBuilder.Query = httpContext.Request.QueryString.ToString();
return uriBuilder.Uri.AbsolutePath;
}
}
}

38
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/ActionResultWrapperFactory.cs

@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Volo.Abp;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping
{
public class ActionResultWrapperFactory : IActionResultWrapperFactory
{
public IActionResultWrapper CreateFor(FilterContext context)
{
Check.NotNull(context, nameof(context));
switch (context)
{
case ResultExecutingContext resultExecutingContext when resultExecutingContext.Result is ObjectResult:
return new ObjectActionResultWrapper();
case ResultExecutingContext resultExecutingContext when resultExecutingContext.Result is JsonResult:
return new JsonActionResultWrapper();
case ResultExecutingContext resultExecutingContext when resultExecutingContext.Result is EmptyResult:
return new EmptyActionResultWrapper();
case PageHandlerExecutedContext pageHandlerExecutedContext when pageHandlerExecutedContext.Result is ObjectResult:
return new ObjectActionResultWrapper();
case PageHandlerExecutedContext pageHandlerExecutedContext when pageHandlerExecutedContext.Result is JsonResult:
return new JsonActionResultWrapper();
case PageHandlerExecutedContext pageHandlerExecutedContext when pageHandlerExecutedContext.Result is EmptyResult:
return new EmptyActionResultWrapper();
default:
return new NullActionResultWrapper();
}
}
}
}

28
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/EmptyActionResultWrapper.cs

@ -0,0 +1,28 @@
using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping
{
public class EmptyActionResultWrapper : IActionResultWrapper
{
public void Wrap(FilterContext context)
{
var options = context.GetRequiredService<IOptions<AbpAspNetCoreMvcWrapperOptions>>().Value;
var code = options.CodeWithEmptyResult(context.HttpContext.RequestServices);
var message = options.MessageWithEmptyResult(context.HttpContext.RequestServices);
switch (context)
{
case ResultExecutingContext resultExecutingContext:
resultExecutingContext.Result = new ObjectResult(new WrapResult(code, message));
return;
case PageHandlerExecutedContext pageHandlerExecutedContext:
pageHandlerExecutedContext.Result = new ObjectResult(new WrapResult(code, message));
return;
}
}
}
}

9
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/IActionResultWrapper.cs

@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Mvc.Filters;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping
{
public interface IActionResultWrapper
{
void Wrap(FilterContext context);
}
}

10
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/IActionResultWrapperFactory.cs

@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping
{
public interface IActionResultWrapperFactory : ITransientDependency
{
IActionResultWrapper CreateFor(FilterContext context);
}
}

40
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/JsonActionResultWrapper.cs

@ -0,0 +1,40 @@
using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using System;
using Volo.Abp.AspNetCore.Mvc;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping
{
public class JsonActionResultWrapper : IActionResultWrapper
{
public void Wrap(FilterContext context)
{
JsonResult jsonResult = null;
switch (context)
{
case ResultExecutingContext resultExecutingContext:
jsonResult = resultExecutingContext.Result as JsonResult;
break;
case PageHandlerExecutedContext pageHandlerExecutedContext:
jsonResult = pageHandlerExecutedContext.Result as JsonResult;
break;
}
if (jsonResult == null)
{
throw new ArgumentException("Action Result should be JsonResult!");
}
if (!(jsonResult.Value is WrapResult))
{
var options = context.GetRequiredService<IOptions<AbpAspNetCoreMvcWrapperOptions>>().Value;
jsonResult.Value = new WrapResult(options.CodeWithFound, jsonResult.Value);
}
}
}
}

12
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/NullActionResultWrapper.cs

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc.Filters;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping
{
public class NullActionResultWrapper : IActionResultWrapper
{
public void Wrap(FilterContext context)
{
}
}
}

51
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/ObjectActionResultWrapper.cs

@ -0,0 +1,51 @@
using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using System;
using Volo.Abp.AspNetCore.Mvc;
namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping
{
public class ObjectActionResultWrapper : IActionResultWrapper
{
public void Wrap(FilterContext context)
{
ObjectResult objectResult = null;
switch (context)
{
case ResultExecutingContext resultExecutingContext:
objectResult = resultExecutingContext.Result as ObjectResult;
break;
case PageHandlerExecutedContext pageHandlerExecutedContext:
objectResult = pageHandlerExecutedContext.Result as ObjectResult;
break;
}
if (objectResult == null)
{
throw new ArgumentException("Action Result should be ObjectResult!");
}
if (!(objectResult.Value is WrapResult))
{
var options = context.GetRequiredService<IOptions<AbpAspNetCoreMvcWrapperOptions>>().Value;
if (objectResult.Value != null)
{
objectResult.Value = new WrapResult(options.CodeWithFound, objectResult.Value);
}
else
{
var code = options.CodeWithEmptyResult(context.HttpContext.RequestServices);
var message = options.MessageWithEmptyResult(context.HttpContext.RequestServices);
objectResult.Value = new WrapResult(code, message);
}
objectResult.DeclaredType = typeof(WrapResult);
}
}
}
}

28
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/Microsoft/AspNetCore/Mvc/ActionContextExtensions.cs

@ -0,0 +1,28 @@
using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Controllers;
namespace Microsoft.AspNetCore.Mvc
{
public static class ActionContextExtensions
{
public static bool CanWarpRsult(this ActionDescriptor actionDescriptor)
{
if (actionDescriptor is ControllerActionDescriptor descriptor)
{
if (descriptor.MethodInfo.IsDefined(typeof(IgnoreWrapResultAttribute), true))
{
return false;
}
if (descriptor.ControllerTypeInfo.IsDefined(typeof(IgnoreWrapResultAttribute), true))
{
return false;
}
return true;
}
return false;
}
}
}

37
aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/README.md

@ -0,0 +1,37 @@
# LINGYUN.Abp.AspNetCore.Mvc.Wrapper
返回值包装器
## 配置使用
```csharp
[DependsOn(typeof(AbpAspNetCoreMvcWrapperModule))]
public class YouProjectModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAspNetCoreMvcWrapperOptions>(options =>
{
// 启用包装器
options.IsEnabled = true;
});
}
}
```
## 配置项说明
* AbpAspNetCoreMvcWrapperOptions.IsEnabled 是否包装返回结果,默认: false
* AbpAspNetCoreMvcWrapperOptions.CodeWithFound 响应成功代码,默认: 0
* AbpAspNetCoreMvcWrapperOptions.HttpStatusCode 包装后的Http响应代码, 默认: 200
* AbpAspNetCoreMvcWrapperOptions.CodeWithEmptyResult 当返回空对象时返回错误代码,默认: 404
* AbpAspNetCoreMvcWrapperOptions.MessageWithEmptyResult 当返回空对象时返回错误消息, 默认: 本地化之后的 NotFound
* AbpAspNetCoreMvcWrapperOptions.IgnorePrefixUrls 指定哪些Url开头的地址不需要处理
* AbpAspNetCoreMvcWrapperOptions.IgnoreNamespaces 指定哪些命名空间开头不需要处理
* AbpAspNetCoreMvcWrapperOptions.IgnoreControllers 指定哪些控制器不需要处理
* AbpAspNetCoreMvcWrapperOptions.IgnoreReturnTypes 指定哪些返回结果类型不需要处理
* AbpAspNetCoreMvcWrapperOptions.IgnoreExceptions 指定哪些异常类型不需要处理
## 其他

2
aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/Properties/launchSettings.json

@ -13,7 +13,7 @@
"launchBrowser": false,
"applicationUrl": "http://0.0.0.0:30010",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}

39
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN.Abp.AspNetCore.Mvc.Tests.csproj

@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<Content Remove="LINGYUN\Abp\AspNetCore\Mvc\Localization\Resources\en.json" />
<Content Remove="LINGYUN\Abp\AspNetCore\Mvc\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\AspNetCore\Mvc\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\AspNetCore\Mvc\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="4.4.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\mvc\LINGYUN.Abp.AspNetCore.Mvc.Wrapper\LINGYUN.Abp.AspNetCore.Mvc.Wrapper.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.AspNetCore.Tests\LINGYUN.Abp.AspNetCore.Tests.csproj" />
</ItemGroup>
</Project>

32
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestBase.cs

@ -0,0 +1,32 @@
using Microsoft.Extensions.Hosting;
using System.IO;
using System.Linq;
namespace LINGYUN.Abp.AspNetCore.Mvc
{
public abstract class AbpAspNetCoreMvcTestBase : AbpAspNetCoreTestBase<Startup>
{
protected override IHostBuilder CreateHostBuilder()
{
return base.CreateHostBuilder();
}
private static string CalculateContentRootPath(string projectFileName, string contentPath)
{
var currentDirectory = Directory.GetCurrentDirectory();
while (!ContainsFile(currentDirectory, projectFileName))
{
currentDirectory = new DirectoryInfo(currentDirectory).Parent.FullName;
}
return Path.Combine(currentDirectory, contentPath);
}
private static bool ContainsFile(string currentDirectory, string projectFileName)
{
return Directory
.GetFiles(currentDirectory, "*.*", SearchOption.TopDirectoryOnly)
.Any(f => Path.GetFileName(f) == projectFileName);
}
}
}

144
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs

@ -0,0 +1,144 @@
using LINGYUN.Abp.AspNetCore.Mvc.GlobalFeatures;
using LINGYUN.Abp.AspNetCore.Mvc.Localization;
using LINGYUN.Abp.AspNetCore.Mvc.Results;
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper;
using Localization.Resources.AbpUi;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ApiExploring;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.Security.Claims;
using Volo.Abp.AspNetCore.TestBase;
using Volo.Abp.Autofac;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
using Volo.Abp.Validation.Localization;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.AspNetCore.Mvc
{
[DependsOn(
typeof(AbpAspNetCoreMvcWrapperModule),
typeof(AbpAspNetCoreTestBaseModule),
typeof(AbpAspNetCoreMvcModule),
typeof(AbpAutofacModule)
)]
public class AbpAspNetCoreMvcTestModule : AbpModule
{
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
{
options.AddAssemblyResource(
typeof(MvcTestResource),
typeof(AbpAspNetCoreMvcTestModule).Assembly
);
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
OneTimeRunner.Run(() =>
{
GlobalFeatureManager.Instance.Modules.GetOrAdd(AbpAspNetCoreMvcTestFeatures.ModuleName,
() => new AbpAspNetCoreMvcTestFeatures(GlobalFeatureManager.Instance))
.EnableAll();
});
context.Services.AddAuthentication(options =>
{
options.DefaultChallengeScheme = "Bearer";
options.DefaultForbidScheme = "Cookie";
}).AddCookie("Cookie").AddJwtBearer("Bearer", _ => { });
context.Services.AddAuthorization(options =>
{
});
Configure<AbpAspNetCoreMvcOptions>(options =>
{
});
Configure<AbpAspNetCoreMvcWrapperOptions>(options =>
{
options.IsEnabled = true;
// 测试先清空
options.IgnoreControllers.Clear();
options.IgnoreExceptions.Clear();
options.IgnoreNamespaces.Clear();
options.IgnorePrefixUrls.Clear();
options.IgnoreReturnTypes.Clear();
// api/abp/api-definition
options.IgnoreControllers.Add<AbpApiDefinitionController>();
// api/abp/application-configuration
options.IgnoreReturnTypes.Add<ApplicationConfigurationDto>();
options.IgnorePrefixUrls.Add("/api/dont/wrap-result-test");
options.IgnoreExceptions.Add<HasDbException>();
});
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAspNetCoreMvcTestModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<MvcTestResource>("en")
.AddBaseTypes(
typeof(AbpUiResource),
typeof(AbpValidationResource)
).AddVirtualJson("/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources");
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
});
Configure<RazorPagesOptions>(options =>
{
options.RootDirectory = "/LINGYUN/Abp/AspNetCore/Mvc";
});
Configure<AbpClaimsMapOptions>(options =>
{
});
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.ErrorCodeNamespaceMappings.Add("Test", typeof(MvcTestResource));
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
app.UseCorrelationId();
app.UseStaticFiles();
app.UseAbpRequestLocalization();
app.UseAbpSecurityHeaders();
app.UseRouting();
app.UseAbpClaimsMap();
app.UseAuthentication();
app.UseAuthorization();
app.UseAuditing();
app.UseUnitOfWork();
app.UseConfiguredEndpoints();
}
}
}

15
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/GlobalFeatures/AbpAspNetCoreMvcTestFeatures.cs

@ -0,0 +1,15 @@
using JetBrains.Annotations;
using Volo.Abp.GlobalFeatures;
namespace LINGYUN.Abp.AspNetCore.Mvc.GlobalFeatures
{
public class AbpAspNetCoreMvcTestFeatures : GlobalModuleFeatures
{
public const string ModuleName = "AbpAspNetCoreMvcTest";
public AbpAspNetCoreMvcTestFeatures([NotNull] GlobalFeatureManager featureManager)
: base(featureManager)
{
}
}
}

6
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Localization/MvcTestResource.cs

@ -0,0 +1,6 @@
namespace LINGYUN.Abp.AspNetCore.Mvc.Localization
{
public class MvcTestResource
{
}
}

6
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/en.json

@ -0,0 +1,6 @@
{
"culture": "en",
"texts": {
"Test:1001": "Test the wrapped exception message."
}
}

6
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/zh-Hans.json

@ -0,0 +1,6 @@
{
"culture": "zh-Hans",
"texts": {
"Test:1001": "测试包装后的异常消息."
}
}

28
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/DontWrapResultController.cs

@ -0,0 +1,28 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using Volo.Abp.AspNetCore.Mvc;
namespace LINGYUN.Abp.AspNetCore.Mvc.Results
{
[Route("api/dont/wrap-result-test")]
public class DontWrapResultController: AbpController
{
[HttpGet]
public TestResultObject Wrap()
{
return new TestResultObject
{
Id = Guid.NewGuid(),
DateTime = Clock.Now,
Double = 3.141592653d,
Integer = 100,
Name = "Not Wrap",
Properties = new Dictionary<string, string>
{
{ "TestKey", "TestValue" }
}
};
}
}
}

8
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/HasDbException.cs

@ -0,0 +1,8 @@
using System.Data.Common;
namespace LINGYUN.Abp.AspNetCore.Mvc.Results
{
public class HasDbException: DbException
{
}
}

16
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/TestResultObject.cs

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.AspNetCore.Mvc.Results
{
public class TestResultObject
{
public Guid Id { get; set; }
public string Name { get; set; }
public DateTime DateTime { get; set; }
public int Integer { get; set; }
public double Double { get; set; }
public Dictionary<string , string> Properties { get; set; }
public TestResultObject() { }
}
}

78
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/WrapResultController.cs

@ -0,0 +1,78 @@
using LINGYUN.Abp.AspNetCore.Mvc.Localization;
using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Data.Common;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
namespace LINGYUN.Abp.AspNetCore.Mvc.Results
{
[Route("api/wrap-result-test")]
public class WrapResultController: AbpController
{
public WrapResultController()
{
LocalizationResource = typeof(MvcTestResource);
}
[HttpGet]
[Route("exception")]
public TestResultObject WrapBusinessException()
{
throw new BusinessException("Test:1001");
}
[HttpGet]
[Route("wrap")]
public TestResultObject Wrap()
{
return new TestResultObject
{
Id = Guid.NewGuid(),
DateTime = Clock.Now,
Double = 3.141592653d,
Integer = 100,
Name = "Wrap",
Properties = new Dictionary<string, string>
{
{ "TestKey", "TestValue" }
}
};
}
[HttpGet]
[Route("wrap-empty")]
public TestResultObject WrapEmpty()
{
return null;
}
[HttpGet]
[Route("not-wrap")]
[IgnoreWrapResult]
public TestResultObject NotWrap()
{
return new TestResultObject
{
Id = Guid.NewGuid(),
DateTime = Clock.Now,
Double = 3.141592653d,
Integer = 100,
Name = "Not Wrap",
Properties = new Dictionary<string, string>
{
{ "TestKey", "TestValue" }
}
};
}
[HttpGet]
[Route("not-wrap-exception")]
public TestResultObject NotWrapHasDbException()
{
throw new HasDbException();
}
}
}

93
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/WrapResultController_Tests.cs

@ -0,0 +1,93 @@
using LINGYUN.Abp.Wrapper;
using Shouldly;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.Http;
using Volo.Abp.Http.Modeling;
using Volo.Abp.Localization;
using Xunit;
namespace LINGYUN.Abp.AspNetCore.Mvc.Results
{
public class WrapResultController_Tests : AbpAspNetCoreMvcTestBase
{
[Fact]
public async Task Should_Return_Not_Wrap_Result_For_Abp_Api_Definition()
{
var result = await GetResponseAsObjectAsync<ApplicationApiDescriptionModel>("/api/abp/api-definition");
result.ShouldNotBeNull();
}
[Fact]
public async Task Should_Return_Not_Wrap_Result_For_Return_Application_Configuration_Dto()
{
var result = await GetResponseAsObjectAsync<ApplicationConfigurationDto>("/api/abp/application-configuration");
result.ShouldNotBeNull();
}
[Fact]
public async Task Should_Return_Not_Wrap_Result_For_Url_Prefix_With_Dont_Wrapper()
{
var result = await GetResponseAsObjectAsync<TestResultObject>("/api/dont/wrap-result-test");
result.ShouldNotBeNull();
result.Name.ShouldBe("Not Wrap");
}
[Fact]
public async Task Should_Return_Wrap_Result_For_Bussiness_Exception()
{
using (CultureHelper.Use("zh-Hans"))
{
var result = await GetResponseAsObjectAsync<WrapResult<TestResultObject>>("/api/wrap-result-test/exception");
result.ShouldNotBeNull();
result.Code.ShouldBe("1001");
result.Message.ShouldBe("测试包装后的异常消息.");
}
using (CultureHelper.Use("en"))
{
var result = await GetResponseAsObjectAsync<WrapResult<TestResultObject>>("/api/wrap-result-test/exception");
result.ShouldNotBeNull();
result.Code.ShouldBe("1001");
result.Message.ShouldBe("Test the wrapped exception message.");
}
}
[Fact]
public async Task Should_Return_Not_Wrap_Result_For_Has_Db_Exception()
{
using (CultureHelper.Use("zh-Hans"))
{
var result = await GetResponseAsObjectAsync<RemoteServiceErrorResponse>("/api/wrap-result-test/not-wrap-exception", System.Net.HttpStatusCode.InternalServerError);
result.ShouldNotBeNull();
result.Error.ShouldNotBeNull();
result.Error.Message.ShouldBe("对不起,在处理你的请求期间,产生了一个服务器内部错误!");
}
}
[Fact]
public async Task Should_Return_Wrap_Result_For_Object_Return_Value()
{
var result = await GetResponseAsObjectAsync<WrapResult<TestResultObject>>("/api/wrap-result-test/wrap");
result.ShouldNotBeNull();
result.Result.Name.ShouldBe("Wrap");
}
[Fact]
public async Task Should_Return_Wrap_Result_For_Empty_Object_Return_Value()
{
var result = await GetResponseAsObjectAsync<WrapResult<TestResultObject>>("/api/wrap-result-test/wrap-empty");
result.Code.ShouldBe("404");
result.Result.ShouldBeNull();
}
[Fact]
public async Task Should_Return_Not_Wrap_Result_For_Object_Return_Value()
{
var result = await GetResponseAsObjectAsync<TestResultObject>("/api/wrap-result-test/not-wrap");
result.ShouldNotBeNull();
result.Name.ShouldBe("Not Wrap");
}
}
}

20
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Startup.cs

@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace LINGYUN.Abp.AspNetCore.Mvc
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddApplication<AbpAspNetCoreMvcTestModule>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
app.InitializeApplication();
}
}
}

27
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/Properties/launchSettings.json

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:53117/",
"sslPort": 44307
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"LINGYUN.Abp.AspNetCore.Mvc.Tests": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}

25
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Tests/LINGYUN.Abp.AspNetCore.Tests.csproj

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="Volo.Abp.Autofac" Version="4.4.0" />
<PackageReference Include="Volo.Abp.AspNetCore.TestBase" Version="4.4.0" />
</ItemGroup>
</Project>

49
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Tests/LINGYUN/Abp/AspNetCore/AbpAspNetCoreTestBase.cs

@ -0,0 +1,49 @@
using Microsoft.Net.Http.Headers;
using Shouldly;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.TestBase;
namespace LINGYUN.Abp.AspNetCore
{
public class AbpAspNetCoreTestBase : AbpAspNetCoreTestBase<Startup>
{
}
public abstract class AbpAspNetCoreTestBase<TStartup> : AbpAspNetCoreIntegratedTestBase<TStartup>
where TStartup : class
{
protected virtual async Task<T> GetResponseAsObjectAsync<T>(string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
{
var strResponse = await GetResponseAsStringAsync(url, expectedStatusCode);
return JsonSerializer.Deserialize<T>(strResponse, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
}
protected virtual async Task<string> GetResponseAsStringAsync(string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
{
using (var response = await GetResponseAsync(url, expectedStatusCode))
{
return await response.Content.ReadAsStringAsync();
}
}
protected virtual async Task<HttpResponseMessage> GetResponseAsync(string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, bool xmlHttpRequest = false)
{
using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, url))
{
requestMessage.Headers.Add("Accept-Language", CultureInfo.CurrentUICulture.Name);
if (xmlHttpRequest)
{
requestMessage.Headers.Add(HeaderNames.XRequestedWith, "XMLHttpRequest");
}
var response = await Client.SendAsync(requestMessage);
response.StatusCode.ShouldBe(expectedStatusCode);
return response;
}
}
}
}

38
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Tests/LINGYUN/Abp/AspNetCore/AbpAspNetCoreTestModule.cs

@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.AspNetCore;
using Volo.Abp.AspNetCore.TestBase;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.AspNetCore
{
[DependsOn(
typeof(AbpAspNetCoreTestBaseModule),
typeof(AbpAspNetCoreModule),
typeof(AbpAutofacModule)
)]
public class AbpAspNetCoreTestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAspNetCoreTestModule>();
//options.FileSets.ReplaceEmbeddedByPhysical<AbpAspNetCoreTestModule>(FindProjectPath(hostingEnvironment));
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
app.UseCorrelationId();
app.UseStaticFiles();
}
}
}

20
aspnet-core/tests/LINGYUN.Abp.AspNetCore.Tests/LINGYUN/Abp/AspNetCore/Startup.cs

@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace LINGYUN.Abp.AspNetCore
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddApplication<AbpAspNetCoreTestModule>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
app.InitializeApplication();
}
}
}
Loading…
Cancel
Save