diff --git a/aspnet-core/LINGYUN.MicroService.Common.sln b/aspnet-core/LINGYUN.MicroService.Common.sln index 4466df56e..f40b45866 100644 --- a/aspnet-core/LINGYUN.MicroService.Common.sln +++ b/aspnet-core/LINGYUN.MicroService.Common.sln @@ -204,7 +204,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Test 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 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Wrapper.Tests", "tests\LINGYUN.Abp.Wrapper.Tests\LINGYUN.Abp.Wrapper.Tests.csproj", "{31AED9ED-29BD-4F2F-8D3A-F00CBB9FC73C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Wrapper.Tests", "tests\LINGYUN.Abp.Wrapper.Tests\LINGYUN.Abp.Wrapper.Tests.csproj", "{31AED9ED-29BD-4F2F-8D3A-F00CBB9FC73C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.HttpClient.Wrapper", "modules\common\LINGYUN.Abp.HttpClient.Wrapper\LINGYUN.Abp.HttpClient.Wrapper.csproj", "{F6CABEE7-DE34-458A-8787-95DFB1DA4762}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -536,6 +538,10 @@ Global {31AED9ED-29BD-4F2F-8D3A-F00CBB9FC73C}.Debug|Any CPU.Build.0 = Debug|Any CPU {31AED9ED-29BD-4F2F-8D3A-F00CBB9FC73C}.Release|Any CPU.ActiveCfg = Release|Any CPU {31AED9ED-29BD-4F2F-8D3A-F00CBB9FC73C}.Release|Any CPU.Build.0 = Release|Any CPU + {F6CABEE7-DE34-458A-8787-95DFB1DA4762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6CABEE7-DE34-458A-8787-95DFB1DA4762}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6CABEE7-DE34-458A-8787-95DFB1DA4762}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6CABEE7-DE34-458A-8787-95DFB1DA4762}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -639,6 +645,7 @@ Global {BD4165DB-F8A4-4715-A05A-CC08F6A18D67} = {B86C21A4-73B7-471E-B73A-B4B905EC9435} {AE5E6DE8-FC02-4633-BA49-C4B8ABADB502} = {B86C21A4-73B7-471E-B73A-B4B905EC9435} {31AED9ED-29BD-4F2F-8D3A-F00CBB9FC73C} = {B86C21A4-73B7-471E-B73A-B4B905EC9435} + {F6CABEE7-DE34-458A-8787-95DFB1DA4762} = {086BE5BE-8594-4DA7-8819-935FEF76DABD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {06C707C6-02C0-411A-AD3B-2D0E13787CB8} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.HttpClient.Wrapper/LINGYUN.Abp.HttpClient.Wrapper.csproj b/aspnet-core/modules/common/LINGYUN.Abp.HttpClient.Wrapper/LINGYUN.Abp.HttpClient.Wrapper.csproj new file mode 100644 index 000000000..cd4d8ad0e --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.HttpClient.Wrapper/LINGYUN.Abp.HttpClient.Wrapper.csproj @@ -0,0 +1,18 @@ + + + + + + net5.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.HttpClient.Wrapper/LINGYUN/Abp/HttpClient/Wrapper/AbpHttpClientWrapperModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.HttpClient.Wrapper/LINGYUN/Abp/HttpClient/Wrapper/AbpHttpClientWrapperModule.cs new file mode 100644 index 000000000..9f7aa9db9 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.HttpClient.Wrapper/LINGYUN/Abp/HttpClient/Wrapper/AbpHttpClientWrapperModule.cs @@ -0,0 +1,13 @@ +using LINGYUN.Abp.Wrapper; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.HttpClient.Wrapper +{ + [DependsOn( + typeof(AbpHttpClientModule), + typeof(AbpWrapperModule))] + public class AbpHttpClientWrapperModule : AbpModule + { + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.HttpClient.Wrapper/LINGYUN/Abp/HttpClient/Wrapper/DynamicHttpProxyInterceptorWrapClientProxy.cs b/aspnet-core/modules/common/LINGYUN.Abp.HttpClient.Wrapper/LINGYUN/Abp/HttpClient/Wrapper/DynamicHttpProxyInterceptorWrapClientProxy.cs new file mode 100644 index 000000000..b568c0da6 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.HttpClient.Wrapper/LINGYUN/Abp/HttpClient/Wrapper/DynamicHttpProxyInterceptorWrapClientProxy.cs @@ -0,0 +1,153 @@ +using LINGYUN.Abp.Wrapper; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Content; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http; +using Volo.Abp.Http.Client; +using Volo.Abp.Http.Client.Authentication; +using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Client.DynamicProxying; + +namespace LINGYUN.Abp.HttpClient.Wrapper +{ + [Dependency(ReplaceServices = true)] + [ExposeServices(typeof(DynamicHttpProxyInterceptorClientProxy<>))] + public class DynamicHttpProxyInterceptorWrapClientProxy + : DynamicHttpProxyInterceptorClientProxy, ITransientDependency + { + protected IOptions WrapperOptions => LazyServiceProvider.LazyGetRequiredService>(); + + protected override async Task RequestAsync(ClientProxyRequestContext requestContext) + { + var response = await RequestAndGetResponseAsync(requestContext); + + var responseContent = response.Content; + + if (typeof(T) == typeof(IRemoteStreamContent) || + typeof(T) == typeof(RemoteStreamContent)) + { + /* returning a class that holds a reference to response + * content just to be sure that GC does not dispose of + * it before we finish doing our work with the stream */ + return (T)(object)new RemoteStreamContent( + await responseContent.ReadAsStreamAsync(), + responseContent.Headers?.ContentDisposition?.FileNameStar ?? + RemoveQuotes(responseContent.Headers?.ContentDisposition?.FileName).ToString(), + responseContent.Headers?.ContentType?.ToString(), + responseContent.Headers?.ContentLength); + } + + var stringContent = await responseContent.ReadAsStringAsync(); + + if (stringContent.IsNullOrWhiteSpace()) + { + return default; + } + + // 对于包装后的结果需要处理 + if (response.Headers.Contains(AbpHttpWrapConsts.AbpWrapResult)) + { + var wrapResult = JsonSerializer.Deserialize>(stringContent); + + ThrowExceptionForResponse(wrapResult); + + if (typeof(T) == typeof(string)) + { + return (T)(object)wrapResult.Result; + } + + return wrapResult.Result; + } + + if (typeof(T) == typeof(string)) + { + return (T)(object)stringContent; + } + + if (stringContent.IsNullOrWhiteSpace()) + { + return default; + } + + return JsonSerializer.Deserialize(stringContent); + } + + public override async Task CallRequestAsync(ClientProxyRequestContext requestContext) + { + var response = await RequestAndGetResponseAsync(requestContext); + // 对于包装后的结果需要处理 + if (response.Headers.Contains(AbpHttpWrapConsts.AbpWrapResult)) + { + var stringContent = await response.Content.ReadAsStringAsync(); + var wrapResult = JsonSerializer.Deserialize(stringContent); + + ThrowExceptionForResponse(wrapResult); + } + + return response.Content; + } + + protected virtual void ThrowExceptionForResponse(WrapResult wrapResult) + { + if (!string.Equals(wrapResult.Code, WrapperOptions.Value.CodeWithSuccess)) + { + var errorInfo = new RemoteServiceErrorInfo( + wrapResult.Message, + wrapResult.Details, + wrapResult.Code); + throw new AbpRemoteCallException(errorInfo) + { + HttpStatusCode = (int)WrapperOptions.Value.HttpStatusCode + }; + } + } + + protected virtual async Task RequestAndGetResponseAsync(ClientProxyRequestContext requestContext) + { + var clientConfig = ClientOptions.Value.HttpClientProxies.GetOrDefault(requestContext.ServiceType) ?? throw new AbpException($"Could not get HttpClientProxyConfig for {requestContext.ServiceType.FullName}."); + var remoteServiceConfig = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(clientConfig.RemoteServiceName); + + var client = HttpClientFactory.Create(clientConfig.RemoteServiceName); + + var apiVersion = await GetApiVersionInfoAsync(requestContext); + var url = remoteServiceConfig.BaseUrl.EnsureEndsWith('/') + await GetUrlWithParametersAsync(requestContext, apiVersion); + + var requestMessage = new HttpRequestMessage(requestContext.Action.GetHttpMethod(), url) + { + Content = await ClientProxyRequestPayloadBuilder.BuildContentAsync(requestContext.Action, requestContext.Arguments, JsonSerializer, apiVersion) + }; + + AddHeaders(requestContext.Arguments, requestContext.Action, requestMessage, apiVersion); + + if (requestContext.Action.AllowAnonymous != true) + { + await ClientAuthenticator.Authenticate( + new RemoteServiceHttpClientAuthenticateContext( + client, + requestMessage, + remoteServiceConfig, + clientConfig.RemoteServiceName + ) + ); + } + + var response = await client.SendAsync( + requestMessage, + HttpCompletionOption.ResponseHeadersRead /*this will buffer only the headers, the content will be used as a stream*/, + GetCancellationToken(requestContext.Arguments) + ); + + if (!response.IsSuccessStatusCode) + { + await ThrowExceptionForResponseAsync(response); + } + + return response; + } + } +} diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpHttpWrapConsts.cs b/aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/AbpHttpWrapConsts.cs similarity index 68% rename from aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpHttpWrapConsts.cs rename to aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/AbpHttpWrapConsts.cs index c3b8e6955..bd0f708b9 100644 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpHttpWrapConsts.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/AbpHttpWrapConsts.cs @@ -1,4 +1,4 @@ -namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper +namespace LINGYUN.Abp.Wrapper { public static class AbpHttpWrapConsts { diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/AbpWrapperOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/AbpWrapperOptions.cs index 9f9f1d971..8d674bceb 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/AbpWrapperOptions.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Wrapper/LINGYUN/Abp/Wrapper/AbpWrapperOptions.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Net; +using Volo.Abp.Collections; namespace LINGYUN.Abp.Wrapper { @@ -10,12 +12,79 @@ namespace LINGYUN.Abp.Wrapper /// 默认: 500 /// public string CodeWithUnhandled { get; set; } + /// + /// 是否启用包装器 + /// + public bool IsEnabled { get; set; } + /// + /// 成功时返回代码 + /// 默认:0 + /// + public string CodeWithSuccess { get; set; } + /// + /// 资源为空时是否提示错误 + /// 默认: false + /// + public bool ErrorWithEmptyResult { get; set; } + /// + /// 资源为空时返回代码 + /// 默认:404 + /// + public Func CodeWithEmptyResult { get; set; } + /// + /// 资源为空时返回错误消息 + /// + public Func MessageWithEmptyResult { get; set; } + /// + /// 包装后的返回状态码 + /// 默认:200 HttpStatusCode.OK + /// + public HttpStatusCode HttpStatusCode { get; set; } + /// + /// 忽略Url开头类型 + /// + public IList IgnorePrefixUrls { get; } + /// + /// 忽略指定命名空间 + /// + public IList IgnoreNamespaces { get; } + /// + /// 忽略控制器 + /// + public ITypeList IgnoreControllers { get; } + /// + /// 忽略返回值 + /// + public ITypeList IgnoreReturnTypes { get; } + /// + /// 忽略异常 + /// + public ITypeList IgnoreExceptions { get; } + /// + /// 忽略服务类型 + /// + public ITypeList IgnoreBaseTypes { get; } internal IDictionary ExceptionHandles { get; } public AbpWrapperOptions() { CodeWithUnhandled = "500"; + CodeWithSuccess = "0"; + HttpStatusCode = HttpStatusCode.OK; + ErrorWithEmptyResult = false; + + IgnorePrefixUrls = new List(); + IgnoreNamespaces = new List(); + + IgnoreControllers = new TypeList(); + IgnoreReturnTypes = new TypeList(); + IgnoreBaseTypes = new TypeList(); + IgnoreExceptions = new TypeList(); + + CodeWithEmptyResult = (_) => "404"; + MessageWithEmptyResult = (_) => "Not Found"; + ExceptionHandles = new Dictionary(); } diff --git a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors.AspNetCore/LINGYUN.Abp.Dapr.Actors.AspNetCore.csproj b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors.AspNetCore/LINGYUN.Abp.Dapr.Actors.AspNetCore.csproj index 1fee35da8..359dc88a4 100644 --- a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors.AspNetCore/LINGYUN.Abp.Dapr.Actors.AspNetCore.csproj +++ b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors.AspNetCore/LINGYUN.Abp.Dapr.Actors.AspNetCore.csproj @@ -12,4 +12,8 @@ + + + + diff --git a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors.AspNetCore/LINGYUN/Abp/Dapr/Actors/AspNetCore/AbpDaprActorsAspNetCoreModule.cs b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors.AspNetCore/LINGYUN/Abp/Dapr/Actors/AspNetCore/AbpDaprActorsAspNetCoreModule.cs index fa267ada0..771e6becc 100644 --- a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors.AspNetCore/LINGYUN/Abp/Dapr/Actors/AspNetCore/AbpDaprActorsAspNetCoreModule.cs +++ b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors.AspNetCore/LINGYUN/Abp/Dapr/Actors/AspNetCore/AbpDaprActorsAspNetCoreModule.cs @@ -1,54 +1,61 @@ -using Dapr.Actors; -using Dapr.Actors.Runtime; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using Volo.Abp.AspNetCore; -using Volo.Abp.Modularity; - -namespace LINGYUN.Abp.Dapr.Actors.AspNetCore -{ - [DependsOn( - typeof(AbpAspNetCoreModule))] - public class AbpDaprActorsAspNetCoreModule : AbpModule - { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - AddDefinitionActor(context.Services); - } - - public override void ConfigureServices(ServiceConfigurationContext context) - { - Configure(options => - { - options.EndpointConfigureActions.Add(endpointContext => - { - endpointContext.Endpoints.MapActorsHandlers(); - }); - }); - } - - private static void AddDefinitionActor(IServiceCollection services) - { - var actorRegistrations = new List(); - - services.OnRegistred(context => - { - if (typeof(IActor).IsAssignableFrom(context.ImplementationType) && - !actorRegistrations.Contains(context.ImplementationType)) - { - var actorRegistration = new ActorRegistration(context.ImplementationType.GetActorTypeInfo()); - - actorRegistrations.Add(actorRegistration); - } - }); - - services.AddActors(options => - { - options.Actors.AddIfNotContains(actorRegistrations); - }); - } - } -} +using Dapr.Actors; +using Dapr.Actors.Runtime; +using LINGYUN.Abp.Wrapper; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using Volo.Abp.AspNetCore; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Dapr.Actors.AspNetCore +{ + [DependsOn( + typeof(AbpAspNetCoreModule), + typeof(AbpWrapperModule))] + public class AbpDaprActorsAspNetCoreModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + AddDefinitionActor(context.Services); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.EndpointConfigureActions.Add(endpointContext => + { + endpointContext.Endpoints.MapActorsHandlers(); + }); + }); + + Configure(options => + { + options.IgnoreBaseTypes.TryAdd(); + }); + } + + private static void AddDefinitionActor(IServiceCollection services) + { + var actorRegistrations = new List(); + + services.OnRegistred(context => + { + if (typeof(IActor).IsAssignableFrom(context.ImplementationType) && + !actorRegistrations.Contains(context.ImplementationType)) + { + var actorRegistration = new ActorRegistration(context.ImplementationType.GetActorTypeInfo()); + + actorRegistrations.Add(actorRegistration); + } + }); + + services.AddActors(options => + { + options.Actors.AddIfNotContains(actorRegistrations); + }); + } + } +} diff --git a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors/LINGYUN/Abp/Dapr/Actors/AbpDaprActorsModule.cs b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors/LINGYUN/Abp/Dapr/Actors/AbpDaprActorsModule.cs index 903968a6f..9a777a844 100644 --- a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors/LINGYUN/Abp/Dapr/Actors/AbpDaprActorsModule.cs +++ b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Actors/LINGYUN/Abp/Dapr/Actors/AbpDaprActorsModule.cs @@ -1,24 +1,24 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Http.Client; -using Volo.Abp.Modularity; - -namespace LINGYUN.Abp.Dapr.Actors -{ - [DependsOn( - typeof(AbpHttpClientModule) - )] - public class AbpDaprActorsModule : AbpModule - { - /// - /// 与AbpHttpClient集成,创建一个命名HttpClient - /// - internal const string DaprHttpClient = "_AbpDaprActorsClient"; - - public override void ConfigureServices(ServiceConfigurationContext context) - { - var configuration = context.Services.GetConfiguration(); - Configure(configuration); - context.Services.AddHttpClient(DaprHttpClient); - } - } -} +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Dapr.Actors +{ + [DependsOn( + typeof(AbpHttpClientModule) + )] + public class AbpDaprActorsModule : AbpModule + { + /// + /// 与AbpHttpClient集成,创建一个命名HttpClient + /// + internal const string DaprHttpClient = "_AbpDaprActorsClient"; + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + Configure(configuration); + context.Services.AddHttpClient(DaprHttpClient); + } + } +} diff --git a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN.Abp.Dapr.Client.csproj b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN.Abp.Dapr.Client.csproj index 71c93a355..0a755bd21 100644 --- a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN.Abp.Dapr.Client.csproj +++ b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN.Abp.Dapr.Client.csproj @@ -12,6 +12,7 @@ + diff --git a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN/Abp/Dapr/Client/AbpDaprClientModule.cs b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN/Abp/Dapr/Client/AbpDaprClientModule.cs index 34d9adb97..b5714474d 100644 --- a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN/Abp/Dapr/Client/AbpDaprClientModule.cs +++ b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN/Abp/Dapr/Client/AbpDaprClientModule.cs @@ -1,11 +1,13 @@ -using Microsoft.Extensions.DependencyInjection; +using LINGYUN.Abp.Wrapper; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Http.Client; using Volo.Abp.Modularity; namespace LINGYUN.Abp.Dapr.Client { [DependsOn( - typeof(AbpHttpClientModule) + typeof(AbpHttpClientModule), + typeof(AbpWrapperModule) )] public class AbpDaprClientModule : AbpModule { diff --git a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN/Abp/Dapr/Client/DynamicProxying/DynamicDaprClientProxyInterceptor.cs b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN/Abp/Dapr/Client/DynamicProxying/DynamicDaprClientProxyInterceptor.cs index d9f9adf3f..b7c24c5fe 100644 --- a/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN/Abp/Dapr/Client/DynamicProxying/DynamicDaprClientProxyInterceptor.cs +++ b/aspnet-core/modules/dapr/LINGYUN.Abp.Dapr.Client/LINGYUN/Abp/Dapr/Client/DynamicProxying/DynamicDaprClientProxyInterceptor.cs @@ -1,312 +1,342 @@ -using Dapr.Client; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Content; -using Volo.Abp.DependencyInjection; -using Volo.Abp.DynamicProxy; -using Volo.Abp.Http; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Client.Authentication; -using Volo.Abp.Http.Client.DynamicProxying; -using Volo.Abp.Http.Modeling; -using Volo.Abp.Http.ProxyScripting.Generators; -using Volo.Abp.Json; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Threading; -using Volo.Abp.Tracing; - -namespace LINGYUN.Abp.Dapr.Client.DynamicProxying -{ - public class DynamicDaprClientProxyInterceptor : AbpInterceptor, ITransientDependency - { - protected static MethodInfo MakeRequestAndGetResultAsyncMethod { get; } - - protected IDaprClientFactory DaprClientFactory { get; } - protected ICancellationTokenProvider CancellationTokenProvider { get; } - protected ICorrelationIdProvider CorrelationIdProvider { get; } - protected ICurrentTenant CurrentTenant { get; } - protected AbpCorrelationIdOptions AbpCorrelationIdOptions { get; } - protected IDynamicProxyHttpClientFactory HttpClientFactory { get; } - protected IDaprApiDescriptionFinder ApiDescriptionFinder { get; } - protected AbpDaprRemoteServiceOptions AbpRemoteServiceOptions { get; } - protected AbpDaprClientProxyOptions ClientProxyOptions { get; } - protected IJsonSerializer JsonSerializer { get; } - protected IRemoteServiceHttpClientAuthenticator ClientAuthenticator { get; } - - public ILogger> Logger { get; set; } - - static DynamicDaprClientProxyInterceptor() - { - MakeRequestAndGetResultAsyncMethod = typeof(DynamicDaprClientProxyInterceptor) - .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance) - .First(m => m.Name == nameof(MakeRequestAndGetResultAsync) && m.IsGenericMethodDefinition); - } - - public DynamicDaprClientProxyInterceptor( - IDaprClientFactory daprClientFactory, - IOptions clientProxyOptions, - IOptionsSnapshot remoteServiceOptions, - IDaprApiDescriptionFinder apiDescriptionFinder, - IJsonSerializer jsonSerializer, - IDynamicProxyHttpClientFactory dynamicProxyHttpClientFactory, - IRemoteServiceHttpClientAuthenticator clientAuthenticator, - ICancellationTokenProvider cancellationTokenProvider, - ICorrelationIdProvider correlationIdProvider, - IOptions correlationIdOptions, - ICurrentTenant currentTenant) - { - DaprClientFactory = daprClientFactory; - CancellationTokenProvider = cancellationTokenProvider; - CorrelationIdProvider = correlationIdProvider; - CurrentTenant = currentTenant; - HttpClientFactory = dynamicProxyHttpClientFactory; - AbpCorrelationIdOptions = correlationIdOptions.Value; - ApiDescriptionFinder = apiDescriptionFinder; - JsonSerializer = jsonSerializer; - ClientAuthenticator = clientAuthenticator; - ClientProxyOptions = clientProxyOptions.Value; - AbpRemoteServiceOptions = remoteServiceOptions.Value; - - Logger = NullLogger>.Instance; - } - - public override async Task InterceptAsync(IAbpMethodInvocation invocation) - { - if (invocation.Method.ReturnType.GenericTypeArguments.IsNullOrEmpty()) - { - await MakeRequestAsync(invocation); - } - else - { - var result = (Task)MakeRequestAndGetResultAsyncMethod - .MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) - .Invoke(this, new object[] { invocation }); - - invocation.ReturnValue = await GetResultAsync( - result, - invocation.Method.ReturnType.GetGenericArguments()[0] - ); - } - } - - private async Task GetResultAsync(Task task, Type resultType) - { - await task; - return typeof(Task<>) - .MakeGenericType(resultType) - .GetProperty(nameof(Task.Result), BindingFlags.Instance | BindingFlags.Public) - .GetValue(task); - } - - private async Task MakeRequestAndGetResultAsync(IAbpMethodInvocation invocation) - { - var responseContent = await MakeRequestAsync(invocation); - - if (typeof(T) == typeof(IRemoteStreamContent)) - { - /* returning a class that holds a reference to response - * content just to be sure that GC does not dispose of - * it before we finish doing our work with the stream */ - return (T)(object)new RemoteStreamContent(await responseContent.ReadAsStreamAsync()) - { - ContentType = responseContent.Headers.ContentType?.ToString() - }; - } - - var stringContent = await responseContent.ReadAsStringAsync(); - if (typeof(T) == typeof(string)) - { - return (T)(object)stringContent; - } - - if (stringContent.IsNullOrWhiteSpace()) - { - return default; - } - - return JsonSerializer.Deserialize(stringContent); - } - - private async Task MakeRequestAsync(IAbpMethodInvocation invocation) - { - var clientConfig = ClientProxyOptions.DaprClientProxies.GetOrDefault(typeof(TService)) ?? throw new AbpException($"Could not get DynamicDaprClientProxyConfig for {typeof(TService).FullName}."); - var remoteServiceConfig = AbpRemoteServiceOptions.RemoteServices.GetConfigurationOrDefault(clientConfig.RemoteServiceName); - - // 遵循远端 api/abp/api-definition - var action = await ApiDescriptionFinder.FindActionAsync( - clientConfig.RemoteServiceName, - remoteServiceConfig.AppId, - typeof(TService), - invocation.Method - ); - - var apiVersion = GetApiVersionInfo(action); - - // See: https://docs.dapr.io/reference/api/service_invocation_api/#examples - // 需要合并端点作为dapr远程调用的方法名称 - var methodName = UrlBuilder.GenerateUrlWithParameters(action, invocation.ArgumentsDictionary, apiVersion); - - var daprClient = DaprClientFactory.CreateClient(clientConfig.RemoteServiceName); - var requestMessage = daprClient.CreateInvokeMethodRequest( - action.GetHttpMethod(), - remoteServiceConfig.AppId, - methodName); - - requestMessage.Content = RequestPayloadBuilder.BuildContent(action, invocation.ArgumentsDictionary, JsonSerializer, apiVersion); - - AddHeaders(invocation, action, requestMessage, apiVersion); - - var httpClient = HttpClientFactory.Create(AbpDaprClientModule.DaprHttpClient); - await ClientAuthenticator.Authenticate( - new RemoteServiceHttpClientAuthenticateContext( - httpClient, - requestMessage, - remoteServiceConfig, - clientConfig.RemoteServiceName - ) - ); - // 其他库可能将授权标头写入到HttpClient中 - if (requestMessage.Headers.Authorization == null && - httpClient.DefaultRequestHeaders.Authorization != null) - { - requestMessage.Headers.Authorization = httpClient.DefaultRequestHeaders.Authorization; - } - - var response = await daprClient.InvokeMethodWithResponseAsync(requestMessage, GetCancellationToken()); - - if (!response.IsSuccessStatusCode) - { - await ThrowExceptionForResponseAsync(response); - } - - return response.Content; - } - - private ApiVersionInfo GetApiVersionInfo(ActionApiDescriptionModel action) - { - var apiVersion = FindBestApiVersion(action); - - //TODO: Make names configurable? - var versionParam = action.Parameters.FirstOrDefault(p => p.Name == "apiVersion" && p.BindingSourceId == ParameterBindingSources.Path) ?? - action.Parameters.FirstOrDefault(p => p.Name == "api-version" && p.BindingSourceId == ParameterBindingSources.Query); - - return new ApiVersionInfo(versionParam?.BindingSourceId, apiVersion); - } - - private string FindBestApiVersion(ActionApiDescriptionModel action) - { - var configuredVersion = GetConfiguredApiVersion(); - - if (action.SupportedVersions.IsNullOrEmpty()) - { - return configuredVersion ?? "1.0"; - } - - if (action.SupportedVersions.Contains(configuredVersion)) - { - return configuredVersion; - } - - return action.SupportedVersions.Last(); //TODO: Ensure to get the latest version! - } - - protected virtual void AddHeaders( - IAbpMethodInvocation invocation, - ActionApiDescriptionModel action, - HttpRequestMessage requestMessage, - ApiVersionInfo apiVersion) - { - //API Version - if (!apiVersion.Version.IsNullOrEmpty()) - { - //TODO: What about other media types? - requestMessage.Headers.Add("accept", $"{MimeTypes.Text.Plain}; v={apiVersion.Version}"); - requestMessage.Headers.Add("accept", $"{MimeTypes.Application.Json}; v={apiVersion.Version}"); - requestMessage.Headers.Add("api-version", apiVersion.Version); - } - - //Header parameters - var headers = action.Parameters.Where(p => p.BindingSourceId == ParameterBindingSources.Header).ToArray(); - foreach (var headerParameter in headers) - { - var value = HttpActionParameterHelper.FindParameterValue(invocation.ArgumentsDictionary, headerParameter); - if (value != null) - { - requestMessage.Headers.Add(headerParameter.Name, value.ToString()); - } - } - - //CorrelationId - requestMessage.Headers.Add(AbpCorrelationIdOptions.HttpHeaderName, CorrelationIdProvider.Get()); - - //TenantId - if (CurrentTenant.Id.HasValue) - { - //TODO: Use AbpAspNetCoreMultiTenancyOptions to get the key - requestMessage.Headers.Add(TenantResolverConsts.DefaultTenantKey, CurrentTenant.Id.Value.ToString()); - } - - //Culture - //TODO: Is that the way we want? Couldn't send the culture (not ui culture) - var currentCulture = CultureInfo.CurrentUICulture.Name ?? CultureInfo.CurrentCulture.Name; - if (!currentCulture.IsNullOrEmpty()) - { - requestMessage.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(currentCulture)); - } - - //X-Requested-With - requestMessage.Headers.Add("X-Requested-With", "XMLHttpRequest"); - } - - private string GetConfiguredApiVersion() - { - var clientConfig = ClientProxyOptions.DaprClientProxies.GetOrDefault(typeof(TService)) - ?? throw new AbpException($"Could not get DynamicDaprClientProxyConfig for {typeof(TService).FullName}."); - - return AbpRemoteServiceOptions.RemoteServices.GetOrDefault(clientConfig.RemoteServiceName)?.Version - ?? AbpRemoteServiceOptions.RemoteServices.Default?.Version; - } - - private async Task ThrowExceptionForResponseAsync(HttpResponseMessage response) - { - if (response.Headers.Contains(AbpHttpConsts.AbpErrorFormat)) - { - var errorResponse = JsonSerializer.Deserialize( - await response.Content.ReadAsStringAsync() - ); - - throw new AbpRemoteCallException(errorResponse.Error) - { - HttpStatusCode = (int)response.StatusCode - }; - } - - throw new AbpRemoteCallException( - new RemoteServiceErrorInfo - { - Message = response.ReasonPhrase, - Code = response.StatusCode.ToString() - } - ) - { - HttpStatusCode = (int)response.StatusCode - }; - } - - protected virtual CancellationToken GetCancellationToken() - { - return CancellationTokenProvider.Token; - } - } -} +using Dapr.Client; +using LINGYUN.Abp.Wrapper; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Content; +using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; +using Volo.Abp.Http; +using Volo.Abp.Http.Client; +using Volo.Abp.Http.Client.Authentication; +using Volo.Abp.Http.Client.DynamicProxying; +using Volo.Abp.Http.Modeling; +using Volo.Abp.Http.ProxyScripting.Generators; +using Volo.Abp.Json; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; +using Volo.Abp.Tracing; + +namespace LINGYUN.Abp.Dapr.Client.DynamicProxying +{ + public class DynamicDaprClientProxyInterceptor : AbpInterceptor, ITransientDependency + { + protected static MethodInfo MakeRequestAndGetResultAsyncMethod { get; } + + protected IDaprClientFactory DaprClientFactory { get; } + protected ICancellationTokenProvider CancellationTokenProvider { get; } + protected ICorrelationIdProvider CorrelationIdProvider { get; } + protected ICurrentTenant CurrentTenant { get; } + protected AbpCorrelationIdOptions AbpCorrelationIdOptions { get; } + protected IDynamicProxyHttpClientFactory HttpClientFactory { get; } + protected IDaprApiDescriptionFinder ApiDescriptionFinder { get; } + protected AbpDaprRemoteServiceOptions AbpRemoteServiceOptions { get; } + protected AbpDaprClientProxyOptions ClientProxyOptions { get; } + protected AbpWrapperOptions WrapperOptions { get; } + protected IJsonSerializer JsonSerializer { get; } + protected IRemoteServiceHttpClientAuthenticator ClientAuthenticator { get; } + + public ILogger> Logger { get; set; } + + static DynamicDaprClientProxyInterceptor() + { + MakeRequestAndGetResultAsyncMethod = typeof(DynamicDaprClientProxyInterceptor) + .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance) + .First(m => m.Name == nameof(MakeRequestAndGetResultAsync) && m.IsGenericMethodDefinition); + } + + public DynamicDaprClientProxyInterceptor( + IDaprClientFactory daprClientFactory, + IOptions clientProxyOptions, + IOptionsSnapshot remoteServiceOptions, + IDaprApiDescriptionFinder apiDescriptionFinder, + IJsonSerializer jsonSerializer, + IDynamicProxyHttpClientFactory dynamicProxyHttpClientFactory, + IRemoteServiceHttpClientAuthenticator clientAuthenticator, + ICancellationTokenProvider cancellationTokenProvider, + ICorrelationIdProvider correlationIdProvider, + IOptions correlationIdOptions, + IOptions wrapperOptions, + ICurrentTenant currentTenant) + { + DaprClientFactory = daprClientFactory; + CancellationTokenProvider = cancellationTokenProvider; + CorrelationIdProvider = correlationIdProvider; + CurrentTenant = currentTenant; + HttpClientFactory = dynamicProxyHttpClientFactory; + AbpCorrelationIdOptions = correlationIdOptions.Value; + ApiDescriptionFinder = apiDescriptionFinder; + JsonSerializer = jsonSerializer; + ClientAuthenticator = clientAuthenticator; + ClientProxyOptions = clientProxyOptions.Value; + AbpRemoteServiceOptions = remoteServiceOptions.Value; + WrapperOptions = wrapperOptions.Value; + + Logger = NullLogger>.Instance; + } + + public override async Task InterceptAsync(IAbpMethodInvocation invocation) + { + if (invocation.Method.ReturnType.GenericTypeArguments.IsNullOrEmpty()) + { + await MakeRequestAsync(invocation); + } + else + { + var result = (Task)MakeRequestAndGetResultAsyncMethod + .MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) + .Invoke(this, new object[] { invocation }); + + invocation.ReturnValue = await GetResultAsync( + result, + invocation.Method.ReturnType.GetGenericArguments()[0] + ); + } + } + + private async Task GetResultAsync(Task task, Type resultType) + { + await task; + return typeof(Task<>) + .MakeGenericType(resultType) + .GetProperty(nameof(Task.Result), BindingFlags.Instance | BindingFlags.Public) + .GetValue(task); + } + + private async Task MakeRequestAndGetResultAsync(IAbpMethodInvocation invocation) + { + var response = await MakeRequestAsync(invocation); + var responseContent = response.Content; + + if (typeof(T) == typeof(IRemoteStreamContent)) + { + /* returning a class that holds a reference to response + * content just to be sure that GC does not dispose of + * it before we finish doing our work with the stream */ + return (T)(object)new RemoteStreamContent(await responseContent.ReadAsStreamAsync()) + { + ContentType = responseContent.Headers.ContentType?.ToString() + }; + } + var stringContent = await responseContent.ReadAsStringAsync(); + + if (stringContent.IsNullOrWhiteSpace()) + { + return default; + } + + // 对于包装后的结果需要处理 + if (response.Headers.Contains(AbpHttpWrapConsts.AbpWrapResult)) + { + var wrapResult = JsonSerializer.Deserialize>(stringContent); + + if (!string.Equals(wrapResult.Code, WrapperOptions.CodeWithSuccess)) + { + var errorInfo = new RemoteServiceErrorInfo( + wrapResult.Message, + wrapResult.Details, + wrapResult.Code); + throw new AbpRemoteCallException(errorInfo) + { + HttpStatusCode = (int)WrapperOptions.HttpStatusCode + }; + } + + if (typeof(T) == typeof(string)) + { + return (T)(object)wrapResult.Result; + } + + return wrapResult.Result; + } + + if (typeof(T) == typeof(string)) + { + return (T)(object)stringContent; + } + + return JsonSerializer.Deserialize(stringContent); + } + + private async Task MakeRequestAsync(IAbpMethodInvocation invocation) + { + var clientConfig = ClientProxyOptions.DaprClientProxies.GetOrDefault(typeof(TService)) ?? throw new AbpException($"Could not get DynamicDaprClientProxyConfig for {typeof(TService).FullName}."); + var remoteServiceConfig = AbpRemoteServiceOptions.RemoteServices.GetConfigurationOrDefault(clientConfig.RemoteServiceName); + + // 遵循远端 api/abp/api-definition + var action = await ApiDescriptionFinder.FindActionAsync( + clientConfig.RemoteServiceName, + remoteServiceConfig.AppId, + typeof(TService), + invocation.Method + ); + + var apiVersion = GetApiVersionInfo(action); + + // See: https://docs.dapr.io/reference/api/service_invocation_api/#examples + // 需要合并端点作为dapr远程调用的方法名称 + var methodName = UrlBuilder.GenerateUrlWithParameters(action, invocation.ArgumentsDictionary, apiVersion); + + var daprClient = DaprClientFactory.CreateClient(clientConfig.RemoteServiceName); + var requestMessage = daprClient.CreateInvokeMethodRequest( + action.GetHttpMethod(), + remoteServiceConfig.AppId, + methodName); + + requestMessage.Content = RequestPayloadBuilder.BuildContent(action, invocation.ArgumentsDictionary, JsonSerializer, apiVersion); + + AddHeaders(invocation, action, requestMessage, apiVersion); + + var httpClient = HttpClientFactory.Create(AbpDaprClientModule.DaprHttpClient); + await ClientAuthenticator.Authenticate( + new RemoteServiceHttpClientAuthenticateContext( + httpClient, + requestMessage, + remoteServiceConfig, + clientConfig.RemoteServiceName + ) + ); + // 其他库可能将授权标头写入到HttpClient中 + if (requestMessage.Headers.Authorization == null && + httpClient.DefaultRequestHeaders.Authorization != null) + { + requestMessage.Headers.Authorization = httpClient.DefaultRequestHeaders.Authorization; + } + + var response = await daprClient.InvokeMethodWithResponseAsync(requestMessage, GetCancellationToken()); + + if (!response.IsSuccessStatusCode) + { + await ThrowExceptionForResponseAsync(response); + } + + return response; + } + + private ApiVersionInfo GetApiVersionInfo(ActionApiDescriptionModel action) + { + var apiVersion = FindBestApiVersion(action); + + //TODO: Make names configurable? + var versionParam = action.Parameters.FirstOrDefault(p => p.Name == "apiVersion" && p.BindingSourceId == ParameterBindingSources.Path) ?? + action.Parameters.FirstOrDefault(p => p.Name == "api-version" && p.BindingSourceId == ParameterBindingSources.Query); + + return new ApiVersionInfo(versionParam?.BindingSourceId, apiVersion); + } + + private string FindBestApiVersion(ActionApiDescriptionModel action) + { + var configuredVersion = GetConfiguredApiVersion(); + + if (action.SupportedVersions.IsNullOrEmpty()) + { + return configuredVersion ?? "1.0"; + } + + if (action.SupportedVersions.Contains(configuredVersion)) + { + return configuredVersion; + } + + return action.SupportedVersions.Last(); //TODO: Ensure to get the latest version! + } + + protected virtual void AddHeaders( + IAbpMethodInvocation invocation, + ActionApiDescriptionModel action, + HttpRequestMessage requestMessage, + ApiVersionInfo apiVersion) + { + //API Version + if (!apiVersion.Version.IsNullOrEmpty()) + { + //TODO: What about other media types? + requestMessage.Headers.Add("accept", $"{MimeTypes.Text.Plain}; v={apiVersion.Version}"); + requestMessage.Headers.Add("accept", $"{MimeTypes.Application.Json}; v={apiVersion.Version}"); + requestMessage.Headers.Add("api-version", apiVersion.Version); + } + + //Header parameters + var headers = action.Parameters.Where(p => p.BindingSourceId == ParameterBindingSources.Header).ToArray(); + foreach (var headerParameter in headers) + { + var value = HttpActionParameterHelper.FindParameterValue(invocation.ArgumentsDictionary, headerParameter); + if (value != null) + { + requestMessage.Headers.Add(headerParameter.Name, value.ToString()); + } + } + + //CorrelationId + requestMessage.Headers.Add(AbpCorrelationIdOptions.HttpHeaderName, CorrelationIdProvider.Get()); + + //TenantId + if (CurrentTenant.Id.HasValue) + { + //TODO: Use AbpAspNetCoreMultiTenancyOptions to get the key + requestMessage.Headers.Add(TenantResolverConsts.DefaultTenantKey, CurrentTenant.Id.Value.ToString()); + } + + //Culture + //TODO: Is that the way we want? Couldn't send the culture (not ui culture) + var currentCulture = CultureInfo.CurrentUICulture.Name ?? CultureInfo.CurrentCulture.Name; + if (!currentCulture.IsNullOrEmpty()) + { + requestMessage.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(currentCulture)); + } + + //X-Requested-With + requestMessage.Headers.Add("X-Requested-With", "XMLHttpRequest"); + } + + private string GetConfiguredApiVersion() + { + var clientConfig = ClientProxyOptions.DaprClientProxies.GetOrDefault(typeof(TService)) + ?? throw new AbpException($"Could not get DynamicDaprClientProxyConfig for {typeof(TService).FullName}."); + + return AbpRemoteServiceOptions.RemoteServices.GetOrDefault(clientConfig.RemoteServiceName)?.Version + ?? AbpRemoteServiceOptions.RemoteServices.Default?.Version; + } + + private async Task ThrowExceptionForResponseAsync(HttpResponseMessage response) + { + if (response.Headers.Contains(AbpHttpConsts.AbpErrorFormat)) + { + var errorResponse = JsonSerializer.Deserialize( + await response.Content.ReadAsStringAsync() + ); + + throw new AbpRemoteCallException(errorResponse.Error) + { + HttpStatusCode = (int)response.StatusCode + }; + } + + throw new AbpRemoteCallException( + new RemoteServiceErrorInfo + { + Message = response.ReasonPhrase, + Code = response.StatusCode.ToString() + } + ) + { + HttpStatusCode = (int)response.StatusCode + }; + } + + protected virtual CancellationToken GetCancellationToken() + { + return CancellationTokenProvider.Token; + } + } +} diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs index 0283ffba6..e8946adf1 100644 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs +++ b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs @@ -41,7 +41,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper mvcOptions.Filters.AddService(typeof(AbpWrapResultFilter)); }); - Configure(options => + Configure(options => { // 即使重写端点也不包装返回结果 // api/abp/api-definition diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperOptions.cs b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperOptions.cs deleted file mode 100644 index 2e974fbe7..000000000 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperOptions.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using Volo.Abp.Collections; - -namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper -{ - public class AbpAspNetCoreMvcWrapperOptions - { - /// - /// 是否启用包装器 - /// - public bool IsEnabled { get; set; } - /// - /// 资源有效时返回代码 - /// 默认:0 - /// - public string CodeWithFound { get; set; } - /// - /// 资源为空时返回代码 - /// 默认:404 - /// - public Func CodeWithEmptyResult { get; set; } - /// - /// 资源为空时返回错误消息 - /// - public Func MessageWithEmptyResult { get; set; } - /// - /// 包装后的返回状态码 - /// 默认:200 HttpStatusCode.OK - /// - public HttpStatusCode HttpStatusCode { get; set; } - /// - /// 忽略Url开头类型 - /// - public IList IgnorePrefixUrls { get; } - /// - /// 忽略指定命名空间 - /// - public IList IgnoreNamespaces { get; } - /// - /// 忽略控制器 - /// - public ITypeList IgnoreControllers { get; } - /// - /// 忽略返回值 - /// - public ITypeList IgnoreReturnTypes { get; } - /// - /// 忽略异常 - /// - public ITypeList IgnoreExceptions { get; } - - public AbpAspNetCoreMvcWrapperOptions() - { - CodeWithFound = "0"; - HttpStatusCode = HttpStatusCode.OK; - - IgnorePrefixUrls = new List(); - IgnoreNamespaces = new List(); - - IgnoreControllers = new TypeList(); - IgnoreReturnTypes = new TypeList(); - IgnoreExceptions = new TypeList(); - - CodeWithEmptyResult = (_) => "404"; - MessageWithEmptyResult = (_) => "Not Found"; - } - } -} diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs index 9913c1046..881fe66a8 100644 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs +++ b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionPageWrapResultFilter.cs @@ -30,7 +30,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling return; } - var wrapResultOptions = context.GetRequiredService>().Value; + var wrapOptions = context.GetRequiredService>().Value; var exceptionHandlingOptions = context.GetRequiredService>().Value; var exceptionToErrorInfoConverter = context.GetRequiredService(); var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients); @@ -58,7 +58,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling context.Result = new ObjectResult(wrapResult); context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true"); - context.HttpContext.Response.StatusCode = (int)wrapResultOptions.HttpStatusCode; + context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode; context.Exception = null; //Handled! } diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs index 983975ec2..1c5584e3f 100644 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs +++ b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ExceptionHandling/AbpExceptionWrapResultFilter.cs @@ -32,7 +32,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling return; } //TODO: Trigger an AbpExceptionHandled event or something like that. - var wrapResultOptions = context.GetRequiredService>().Value; + var wrapOptions = context.GetRequiredService>().Value; var exceptionHandlingOptions = context.GetRequiredService>().Value; var exceptionToErrorInfoConverter = context.GetRequiredService(); var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, exceptionHandlingOptions.SendExceptionsDetailsToClients); @@ -61,7 +61,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ExceptionHandling context.Result = new ObjectResult(wrapResult); context.HttpContext.Response.Headers.Add(AbpHttpWrapConsts.AbpWrapResult, "true"); - context.HttpContext.Response.StatusCode = (int)wrapResultOptions.HttpStatusCode; + context.HttpContext.Response.StatusCode = (int)wrapOptions.HttpStatusCode; context.Exception = null; //Handled! } diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Filters/AbpWrapResultFilter.cs b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Filters/AbpWrapResultFilter.cs index 42a5b4bc2..34ce47c55 100644 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Filters/AbpWrapResultFilter.cs +++ b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Filters/AbpWrapResultFilter.cs @@ -1,4 +1,5 @@ using LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping; +using LINGYUN.Abp.Wrapper; using Microsoft.AspNetCore.Mvc.Filters; using System.Threading.Tasks; using Volo.Abp.AspNetCore.Mvc; diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs index e6861de37..9de0b99fc 100644 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs +++ b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs @@ -6,18 +6,16 @@ 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; using Volo.Abp.Threading; namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper { public class WrapResultChecker : IWrapResultChecker, ISingletonDependency { - protected AbpAspNetCoreMvcWrapperOptions Options { get; } + protected AbpWrapperOptions Options { get; } - public WrapResultChecker(IOptionsMonitor optionsMonitor) + public WrapResultChecker(IOptionsMonitor optionsMonitor) { Options = optionsMonitor.CurrentValue; } diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/EmptyActionResultWrapper.cs b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/EmptyActionResultWrapper.cs index 6904ae8cc..98fe39b6c 100644 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/EmptyActionResultWrapper.cs +++ b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/EmptyActionResultWrapper.cs @@ -10,7 +10,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping { public void Wrap(FilterContext context) { - var options = context.GetRequiredService>().Value; + var options = context.GetRequiredService>().Value; var code = options.CodeWithEmptyResult(context.HttpContext.RequestServices); var message = options.MessageWithEmptyResult(context.HttpContext.RequestServices); switch (context) diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/JsonActionResultWrapper.cs b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/JsonActionResultWrapper.cs index 7ce4a6110..18d172585 100644 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/JsonActionResultWrapper.cs +++ b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/JsonActionResultWrapper.cs @@ -31,9 +31,9 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping if (!(jsonResult.Value is WrapResult)) { - var options = context.GetRequiredService>().Value; + var options = context.GetRequiredService>().Value; - jsonResult.Value = new WrapResult(options.CodeWithFound, jsonResult.Value); + jsonResult.Value = new WrapResult(options.CodeWithSuccess, jsonResult.Value); } } } diff --git a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/ObjectActionResultWrapper.cs b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/ObjectActionResultWrapper.cs index b1cd7dbc9..fc15666f4 100644 --- a/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/ObjectActionResultWrapper.cs +++ b/aspnet-core/modules/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/Wraping/ObjectActionResultWrapper.cs @@ -31,18 +31,18 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.Wraping if (!(objectResult.Value is WrapResult)) { - var options = context.GetRequiredService>().Value; + var options = context.GetRequiredService>().Value; - if (objectResult.Value != null) - { - objectResult.Value = new WrapResult(options.CodeWithFound, objectResult.Value); - } - else + if (objectResult.Value == null && options.ErrorWithEmptyResult) { var code = options.CodeWithEmptyResult(context.HttpContext.RequestServices); var message = options.MessageWithEmptyResult(context.HttpContext.RequestServices); objectResult.Value = new WrapResult(code, message); } + else + { + objectResult.Value = new WrapResult(options.CodeWithSuccess, objectResult.Value); + } objectResult.DeclaredType = typeof(WrapResult); } diff --git a/aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 27229a7a9..ba8d98a4f 100644 --- a/aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -2,6 +2,7 @@ using LINGYUN.Abp.AspNetCore.Mvc.Localization; using LINGYUN.Abp.AspNetCore.Mvc.Results; using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; +using LINGYUN.Abp.Wrapper; using Localization.Resources.AbpUi; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc.RazorPages; @@ -70,7 +71,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc { }); - Configure(options => + Configure(options => { options.IsEnabled = true; diff --git a/aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/WrapResultController_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/WrapResultController_Tests.cs index 165fa5b57..0ddf305ca 100644 --- a/aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/WrapResultController_Tests.cs +++ b/aspnet-core/tests/LINGYUN.Abp.AspNetCore.Mvc.Tests/LINGYUN/Abp/AspNetCore/Mvc/Results/WrapResultController_Tests.cs @@ -86,7 +86,7 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Results public async Task Should_Return_Wrap_Result_For_Empty_Object_Return_Value() { var result = await GetResponseAsObjectAsync>("/api/wrap-result-test/wrap-empty"); - result.Code.ShouldBe("404"); + result.Code.ShouldBe("0"); result.Result.ShouldBeNull(); } diff --git a/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN.Abp.Dapr.AspNetCore.TestHost.csproj b/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN.Abp.Dapr.AspNetCore.TestHost.csproj index bf51109b6..670731b58 100644 --- a/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN.Abp.Dapr.AspNetCore.TestHost.csproj +++ b/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN.Abp.Dapr.AspNetCore.TestHost.csproj @@ -11,7 +11,9 @@ + + diff --git a/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN/Abp/Dapr/AbpDaprAspNetCoreTestHostModule.cs b/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN/Abp/Dapr/AbpDaprAspNetCoreTestHostModule.cs index 1d888b099..6ce090d43 100644 --- a/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN/Abp/Dapr/AbpDaprAspNetCoreTestHostModule.cs +++ b/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN/Abp/Dapr/AbpDaprAspNetCoreTestHostModule.cs @@ -1,39 +1,51 @@ -using LINGYUN.Abp.Dapr.Actors.AspNetCore; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp; -using Volo.Abp.AspNetCore.Mvc; -using Volo.Abp.Modularity; - -namespace LINGYUN.Abp.Dapr -{ - [DependsOn( - typeof(AbpAspNetCoreMvcModule), - typeof(AbpDaprActorsAspNetCoreModule) - )] - public class AbpDaprAspNetCoreTestHostModule : AbpModule - { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - Configure(builder => - { - builder.AddApplicationPart(typeof(AbpDaprAspNetCoreTestHostModule).Assembly); - }); - } - - public override void ConfigureServices(ServiceConfigurationContext context) - { - var hostingEnvironment = context.Services.GetHostingEnvironment(); - var configuration = context.Services.GetConfiguration(); - } - - public override void OnApplicationInitialization(ApplicationInitializationContext context) - { - var app = context.GetApplicationBuilder(); - - app.UseRouting(); - app.UseAuditing(); - app.UseConfiguredEndpoints(); - } - } -} +using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; +using LINGYUN.Abp.Dapr.Actors.AspNetCore; +using LINGYUN.Abp.Dapr.ServiceInvocation; +using LINGYUN.Abp.Wrapper; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Dapr +{ + [DependsOn( + typeof(AbpDaprActorsAspNetCoreModule), + typeof(AbpAspNetCoreMvcWrapperModule) + )] + public class AbpDaprAspNetCoreTestHostModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + Configure(builder => + { + builder.AddApplicationPart(typeof(AbpDaprAspNetCoreTestHostModule).Assembly); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = context.Services.GetConfiguration(); + + Configure(options => + { + options.IsEnabled = true; + + options.IgnoreReturnTypes.TryAdd(); + options.IgnoreReturnTypes.TryAdd>(); + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + + app.UseRouting(); + app.UseAuditing(); + app.UseConfiguredEndpoints(); + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN/Abp/Dapr/ServiceInvocation/TestAppService.cs b/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN/Abp/Dapr/ServiceInvocation/TestAppService.cs index 355ef0a37..01373762e 100644 --- a/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN/Abp/Dapr/ServiceInvocation/TestAppService.cs +++ b/aspnet-core/tests/LINGYUN.Abp.Dapr.AspNetCore.TestHost/LINGYUN/Abp/Dapr/ServiceInvocation/TestAppService.cs @@ -1,41 +1,53 @@ -using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.AspNetCore.Mvc; - -namespace LINGYUN.Abp.Dapr.ServiceInvocation -{ - [RemoteService(Name = "TestDapr")] - [Route("api/dapr/test")] - public class TestAppService : AbpController, ITestAppService - { - private static int _inctement; - private readonly List _cache = new List - { - new NameValue("name1", "value1"), - new NameValue("name2", "value2"), - new NameValue("name3", "value3"), - new NameValue("name4", "value4"), - new NameValue("name5", "value5") - }; - - [HttpGet] - public Task> GetAsync() - { - return Task.FromResult(new ListResultDto(_cache)); - } - - [HttpPut] - public Task UpdateAsync() - { - Interlocked.Increment(ref _inctement); - - _cache[0].Value = $"value:updated:{_inctement}"; - - return Task.FromResult(_cache[0]); - } - } -} +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.AspNetCore.Mvc; + +namespace LINGYUN.Abp.Dapr.ServiceInvocation +{ + [RemoteService(Name = "TestDapr")] + [Route("api/dapr/test")] + public class TestAppService : AbpController, ITestAppService + { + private static int _inctement; + private readonly List _cache = new List + { + new NameValue("name1", "value1"), + new NameValue("name2", "value2"), + new NameValue("name3", "value3"), + new NameValue("name4", "value4"), + new NameValue("name5", "value5") + }; + + [HttpGet] + public Task> GetAsync() + { + return Task.FromResult(new ListResultDto(_cache)); + } + + [HttpPut] + public Task UpdateAsync() + { + Interlocked.Increment(ref _inctement); + + _cache[0].Value = $"value:updated:{_inctement}"; + + return Task.FromResult(_cache[0]); + } + + [HttpGet] + [Route("{name}")] + public Task GetWrapedAsync(string name) + { + var obj = new TestNeedWrapObject + { + Name = name + }; + + return Task.FromResult(obj); + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Dapr.Client.Tests/LINGYUN/Abp/Dapr/Client/Tests/TestAppServiceTests.cs b/aspnet-core/tests/LINGYUN.Abp.Dapr.Client.Tests/LINGYUN/Abp/Dapr/Client/Tests/TestAppServiceTests.cs index 26520b04f..40329a2f0 100644 --- a/aspnet-core/tests/LINGYUN.Abp.Dapr.Client.Tests/LINGYUN/Abp/Dapr/Client/Tests/TestAppServiceTests.cs +++ b/aspnet-core/tests/LINGYUN.Abp.Dapr.Client.Tests/LINGYUN/Abp/Dapr/Client/Tests/TestAppServiceTests.cs @@ -1,33 +1,41 @@ -using LINGYUN.Abp.Dapr.ServiceInvocation; -using Shouldly; -using System.Threading.Tasks; -using Xunit; - -namespace LINGYUN.Abp.Dapr.Client.Tests -{ - public class TestAppServiceTests : AbpDaptClientTestBase - { - private readonly ITestAppService _service; - - public TestAppServiceTests() - { - _service = GetRequiredService(); - } - - [Fact] - public async Task Get_Result_Items_Count_Should_5() - { - var result = await _service.GetAsync(); - - result.Items.Count.ShouldBe(5); - } - - [Fact] - public async Task Update_Result_Value_Should_Value_Updated_1() - { - var result = await _service.UpdateAsync(); - - result.Value.ShouldBe("value:updated:1"); - } - } -} +using LINGYUN.Abp.Dapr.ServiceInvocation; +using Shouldly; +using System.Threading.Tasks; +using Xunit; + +namespace LINGYUN.Abp.Dapr.Client.Tests +{ + public class TestAppServiceTests : AbpDaptClientTestBase + { + private readonly ITestAppService _service; + + public TestAppServiceTests() + { + _service = GetRequiredService(); + } + + [Fact] + public async Task Get_Result_Items_Count_Should_5() + { + var result = await _service.GetAsync(); + + result.Items.Count.ShouldBe(5); + } + + [Fact] + public async Task Should_Get_Wraped_Object() + { + var result = await _service.GetWrapedAsync("Test"); + + result.Name.ShouldBe("Test"); + } + + [Fact] + public async Task Update_Result_Value_Should_Value_Updated_1() + { + var result = await _service.UpdateAsync(); + + result.Value.ShouldBe("value:updated:1"); + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/AbpDaprTestModule.cs b/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/AbpDaprTestModule.cs index 6fa217477..b0be477fa 100644 --- a/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/AbpDaprTestModule.cs +++ b/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/AbpDaprTestModule.cs @@ -1,11 +1,12 @@ -using Volo.Abp.Application; -using Volo.Abp.Modularity; - -namespace LINGYUN.Abp.Dapr -{ - [DependsOn( - typeof(AbpDddApplicationContractsModule))] - public class AbpDaprTestModule : AbpModule - { - } -} +using Volo.Abp.Application; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Dapr +{ + [DependsOn( + typeof(AbpDddApplicationContractsModule))] + public class AbpDaprTestModule : AbpModule + { + + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/ServiceInvocation/ITestAppService.cs b/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/ServiceInvocation/ITestAppService.cs index 8f779a866..c543aa5b3 100644 --- a/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/ServiceInvocation/ITestAppService.cs +++ b/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/ServiceInvocation/ITestAppService.cs @@ -1,14 +1,16 @@ -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; - -namespace LINGYUN.Abp.Dapr.ServiceInvocation -{ - public interface ITestAppService : IApplicationService - { - Task> GetAsync(); - - Task UpdateAsync(); - } -} +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.Dapr.ServiceInvocation +{ + public interface ITestAppService : IApplicationService + { + Task> GetAsync(); + + Task UpdateAsync(); + + Task GetWrapedAsync(string name); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/TestNeedWrapObject.cs b/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/TestNeedWrapObject.cs new file mode 100644 index 000000000..3fa6c9425 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Dapr.Tests/LINGYUN/Abp/Dapr/TestNeedWrapObject.cs @@ -0,0 +1,7 @@ +namespace LINGYUN.Abp.Dapr +{ + public class TestNeedWrapObject + { + public string Name { get; set; } + } +}