mirror of https://github.com/abpframework/abp.git
20 changed files with 673 additions and 12 deletions
@ -0,0 +1,24 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.Http.ProxyScripting; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.ProxyScripting |
||||
|
{ |
||||
|
//TODO: [DontWrapResult]
|
||||
|
//TODO: [DisableAuditing]
|
||||
|
public class AbpServiceProxiesController : AbpController |
||||
|
{ |
||||
|
private readonly IProxyScriptManager _proxyScriptManager; |
||||
|
|
||||
|
public AbpServiceProxiesController(IProxyScriptManager proxyScriptManager) |
||||
|
{ |
||||
|
_proxyScriptManager = proxyScriptManager; |
||||
|
} |
||||
|
|
||||
|
[Produces("text/javascript", "text/plain")] |
||||
|
public string GetAll(ServiceProxyGenerationModel model) |
||||
|
{ |
||||
|
model.Normalize(); |
||||
|
return _proxyScriptManager.GetScript(model.CreateOptions()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using Volo.Abp.Http.ProxyScripting; |
||||
|
using Volo.Abp.Http.ProxyScripting.Generators.JQuery; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.ProxyScripting |
||||
|
{ |
||||
|
public class ServiceProxyGenerationModel //: TODO: IShouldNormalize
|
||||
|
{ |
||||
|
public string Type { get; set; } |
||||
|
|
||||
|
public bool UseCache { get; set; } |
||||
|
|
||||
|
public string Modules { get; set; } |
||||
|
|
||||
|
public string Controllers { get; set; } |
||||
|
|
||||
|
public string Actions { get; set; } |
||||
|
|
||||
|
public ServiceProxyGenerationModel() |
||||
|
{ |
||||
|
UseCache = true; |
||||
|
} |
||||
|
|
||||
|
public void Normalize() |
||||
|
{ |
||||
|
if (Type.IsNullOrEmpty()) |
||||
|
{ |
||||
|
Type = JQueryProxyScriptGenerator.Name; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public ProxyScriptingModel CreateOptions() |
||||
|
{ |
||||
|
var options = new ProxyScriptingModel(Type, UseCache); |
||||
|
|
||||
|
if (!Modules.IsNullOrEmpty()) |
||||
|
{ |
||||
|
options.Modules = Modules.Split('|').Select(m => m.Trim()).ToArray(); |
||||
|
} |
||||
|
|
||||
|
if (!Controllers.IsNullOrEmpty()) |
||||
|
{ |
||||
|
options.Controllers = Controllers.Split('|').Select(m => m.Trim()).ToArray(); |
||||
|
} |
||||
|
|
||||
|
if (!Actions.IsNullOrEmpty()) |
||||
|
{ |
||||
|
options.Actions = Actions.Split('|').Select(m => m.Trim()).ToArray(); |
||||
|
} |
||||
|
|
||||
|
return options; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.Http.ProxyScripting.Configuration |
||||
|
{ |
||||
|
public class AbpApiProxyScriptingOptions |
||||
|
{ |
||||
|
public IDictionary<string, Type> Generators { get; } |
||||
|
|
||||
|
public AbpApiProxyScriptingOptions() |
||||
|
{ |
||||
|
Generators = new Dictionary<string, Type>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using Volo.Abp.Http.Modeling; |
||||
|
|
||||
|
namespace Volo.Abp.Http.ProxyScripting.Generators |
||||
|
{ |
||||
|
public interface IProxyScriptGenerator |
||||
|
{ |
||||
|
string CreateScript(ApplicationApiDescriptionModel model); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,121 @@ |
|||||
|
using System; |
||||
|
using System.Text; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Http.Modeling; |
||||
|
|
||||
|
namespace Volo.Abp.Http.ProxyScripting.Generators.JQuery |
||||
|
{ |
||||
|
public class JQueryProxyScriptGenerator : IProxyScriptGenerator, ITransientDependency |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// "jquery".
|
||||
|
/// </summary>
|
||||
|
public const string Name = "jquery"; |
||||
|
|
||||
|
public string CreateScript(ApplicationApiDescriptionModel model) |
||||
|
{ |
||||
|
var script = new StringBuilder(); |
||||
|
|
||||
|
script.AppendLine("/* This file is automatically generated by ABP framework to use MVC Controllers from javascript. */"); |
||||
|
script.AppendLine(); |
||||
|
script.AppendLine("var abp = abp || {};"); |
||||
|
script.AppendLine("abp.services = abp.services || {};"); |
||||
|
|
||||
|
foreach (var module in model.Modules.Values) |
||||
|
{ |
||||
|
script.AppendLine(); |
||||
|
AddModuleScript(script, module); |
||||
|
} |
||||
|
|
||||
|
return script.ToString(); |
||||
|
} |
||||
|
|
||||
|
private static void AddModuleScript(StringBuilder script, ModuleApiDescriptionModel module) |
||||
|
{ |
||||
|
script.AppendLine($"// module '{module.Name.ToCamelCase()}'"); |
||||
|
script.AppendLine("(function(){"); |
||||
|
script.AppendLine(); |
||||
|
script.AppendLine($" abp.services.{module.Name.ToCamelCase()} = abp.services.{module.Name.ToCamelCase()} || {{}};"); |
||||
|
|
||||
|
foreach (var controller in module.Controllers.Values) |
||||
|
{ |
||||
|
script.AppendLine(); |
||||
|
AddControllerScript(script, module, controller); |
||||
|
} |
||||
|
|
||||
|
script.AppendLine(); |
||||
|
script.AppendLine("})();"); |
||||
|
} |
||||
|
|
||||
|
private static void AddControllerScript(StringBuilder script, ModuleApiDescriptionModel module, ControllerApiDescriptionModel controller) |
||||
|
{ |
||||
|
script.AppendLine($" // controller '{controller.ControllerName.ToCamelCase()}'"); |
||||
|
script.AppendLine(" (function(){"); |
||||
|
script.AppendLine(); |
||||
|
|
||||
|
script.AppendLine($" abp.services.{module.Name.ToCamelCase()}.{controller.ControllerName.ToCamelCase()} = abp.services.{module.Name.ToCamelCase()}.{controller.ControllerName.ToCamelCase()} || {{}};"); |
||||
|
|
||||
|
foreach (var action in controller.Actions.Values) |
||||
|
{ |
||||
|
script.AppendLine(); |
||||
|
AddActionScript(script, module, controller, action); |
||||
|
} |
||||
|
|
||||
|
script.AppendLine(); |
||||
|
script.AppendLine(" })();"); |
||||
|
} |
||||
|
|
||||
|
private static void AddActionScript(StringBuilder script, ModuleApiDescriptionModel module, ControllerApiDescriptionModel controller, ActionApiDescriptionModel action) |
||||
|
{ |
||||
|
var parameterList = ProxyScriptingJsFuncHelper.GenerateJsFuncParameterList(action, "ajaxParams"); |
||||
|
|
||||
|
script.AppendLine($" // action '{action.NameOnClass.ToCamelCase()}'"); |
||||
|
script.AppendLine($" abp.services.{module.Name.ToCamelCase()}.{controller.ControllerName.ToCamelCase()}{ProxyScriptingJsFuncHelper.WrapWithBracketsOrWithDotPrefix(action.NameOnClass.ToCamelCase())} = function({parameterList}) {{"); |
||||
|
script.AppendLine(" return abp.ajax($.extend(true, {"); |
||||
|
|
||||
|
AddAjaxCallParameters(script, controller, action); |
||||
|
|
||||
|
script.AppendLine(" }, ajaxParams));;"); |
||||
|
script.AppendLine(" };"); |
||||
|
} |
||||
|
|
||||
|
private static void AddAjaxCallParameters(StringBuilder script, ControllerApiDescriptionModel controller, ActionApiDescriptionModel action) |
||||
|
{ |
||||
|
var httpMethod = action.HttpMethod?.ToUpperInvariant() ?? "POST"; |
||||
|
|
||||
|
script.AppendLine(" url: abp.appPath + '" + ProxyScriptingHelper.GenerateUrlWithParameters(action) + "',"); |
||||
|
script.Append(" type: '" + httpMethod + "'"); |
||||
|
|
||||
|
if (action.ReturnValue.Type == typeof(void)) |
||||
|
{ |
||||
|
script.AppendLine(","); |
||||
|
script.Append(" dataType: null"); |
||||
|
} |
||||
|
|
||||
|
var headers = ProxyScriptingHelper.GenerateHeaders(action, 8); |
||||
|
if (headers != null) |
||||
|
{ |
||||
|
script.AppendLine(","); |
||||
|
script.Append(" headers: " + headers); |
||||
|
} |
||||
|
|
||||
|
var body = ProxyScriptingHelper.GenerateBody(action); |
||||
|
if (!body.IsNullOrEmpty()) |
||||
|
{ |
||||
|
script.AppendLine(","); |
||||
|
script.Append(" data: JSON.stringify(" + body + ")"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var formData = ProxyScriptingHelper.GenerateFormPostData(action, 8); |
||||
|
if (!formData.IsNullOrEmpty()) |
||||
|
{ |
||||
|
script.AppendLine(","); |
||||
|
script.Append(" data: " + formData); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
script.AppendLine(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
namespace Volo.Abp.Http.ProxyScripting.Generators |
||||
|
{ |
||||
|
public static class ParameterBindingSources |
||||
|
{ |
||||
|
public const string ModelBinding = "ModelBinding"; |
||||
|
public const string Query = "Query"; |
||||
|
public const string Body = "Body"; |
||||
|
public const string Path = "Path"; |
||||
|
public const string Form = "Form"; |
||||
|
public const string Header = "Header"; |
||||
|
public const string Custom = "Custom"; |
||||
|
public const string Services = "Services"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,144 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Volo.Abp.Http.Modeling; |
||||
|
|
||||
|
namespace Volo.Abp.Http.ProxyScripting.Generators |
||||
|
{ |
||||
|
internal static class ProxyScriptingHelper |
||||
|
{ |
||||
|
public const string DefaultHttpVerb = "POST"; |
||||
|
|
||||
|
public static string GenerateUrlWithParameters(ActionApiDescriptionModel action) |
||||
|
{ |
||||
|
//TODO: Can be optimized using StringBuilder?
|
||||
|
var url = ReplacePathVariables(action.Url, action.Parameters); |
||||
|
url = AddQueryStringParameters(url, action.Parameters); |
||||
|
return url; |
||||
|
} |
||||
|
|
||||
|
public static string GenerateHeaders(ActionApiDescriptionModel action, int indent = 0) |
||||
|
{ |
||||
|
var parameters = action |
||||
|
.Parameters |
||||
|
.Where(p => p.BindingSourceId == ParameterBindingSources.Header) |
||||
|
.ToArray(); |
||||
|
|
||||
|
if (!parameters.Any()) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return ProxyScriptingJsFuncHelper.CreateJsObjectLiteral(parameters, indent); |
||||
|
} |
||||
|
|
||||
|
public static string GenerateBody(ActionApiDescriptionModel action) |
||||
|
{ |
||||
|
var parameters = action |
||||
|
.Parameters |
||||
|
.Where(p => p.BindingSourceId == ParameterBindingSources.Body) |
||||
|
.ToArray(); |
||||
|
|
||||
|
if (parameters.Length <= 0) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
if (parameters.Length > 1) |
||||
|
{ |
||||
|
throw new AbpException( |
||||
|
$"Only one complex type allowed as argument to a controller action that's binding source is 'Body'. But {action.UniqueName} ({action.Url}) contains more than one!" |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return ProxyScriptingJsFuncHelper.GetParamNameInJsFunc(parameters[0]); |
||||
|
} |
||||
|
|
||||
|
public static string GenerateFormPostData(ActionApiDescriptionModel action, int indent = 0) |
||||
|
{ |
||||
|
var parameters = action |
||||
|
.Parameters |
||||
|
.Where(p => p.BindingSourceId == ParameterBindingSources.Form) |
||||
|
.ToArray(); |
||||
|
|
||||
|
if (!parameters.Any()) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return ProxyScriptingJsFuncHelper.CreateJsObjectLiteral(parameters, indent); |
||||
|
} |
||||
|
|
||||
|
private static string ReplacePathVariables(string url, IList<ParameterApiDescriptionModel> actionParameters) |
||||
|
{ |
||||
|
var pathParameters = actionParameters |
||||
|
.Where(p => p.BindingSourceId == ParameterBindingSources.Path) |
||||
|
.ToArray(); |
||||
|
|
||||
|
if (!pathParameters.Any()) |
||||
|
{ |
||||
|
return url; |
||||
|
} |
||||
|
|
||||
|
foreach (var pathParameter in pathParameters) |
||||
|
{ |
||||
|
url = url.Replace($"{{{pathParameter.Name}}}", $"' + {ProxyScriptingJsFuncHelper.GetParamNameInJsFunc(pathParameter)} + '"); |
||||
|
} |
||||
|
|
||||
|
return url; |
||||
|
} |
||||
|
|
||||
|
private static string AddQueryStringParameters(string url, IList<ParameterApiDescriptionModel> actionParameters) |
||||
|
{ |
||||
|
var queryStringParameters = actionParameters |
||||
|
.Where(p => p.BindingSourceId.IsIn(ParameterBindingSources.ModelBinding, ParameterBindingSources.Query)) |
||||
|
.ToArray(); |
||||
|
|
||||
|
if (!queryStringParameters.Any()) |
||||
|
{ |
||||
|
return url; |
||||
|
} |
||||
|
|
||||
|
var qsBuilderParams = queryStringParameters |
||||
|
.Select(p => $"{{ name: '{p.Name.ToCamelCase()}', value: {ProxyScriptingJsFuncHelper.GetParamNameInJsFunc(p)} }}") |
||||
|
.JoinAsString(", "); |
||||
|
|
||||
|
return url + $"' + abp.utils.buildQueryString([{qsBuilderParams}]) + '"; |
||||
|
} |
||||
|
|
||||
|
public static string GetConventionalVerbForMethodName(string methodName) |
||||
|
{ |
||||
|
if (methodName.StartsWith("Get", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
return "GET"; |
||||
|
} |
||||
|
|
||||
|
if (methodName.StartsWith("Put", StringComparison.OrdinalIgnoreCase) || |
||||
|
methodName.StartsWith("Update", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
return "PUT"; |
||||
|
} |
||||
|
|
||||
|
if (methodName.StartsWith("Delete", StringComparison.OrdinalIgnoreCase) || |
||||
|
methodName.StartsWith("Remove", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
return "DELETE"; |
||||
|
} |
||||
|
|
||||
|
if (methodName.StartsWith("Patch", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
return "PATCH"; |
||||
|
} |
||||
|
|
||||
|
if (methodName.StartsWith("Post", StringComparison.OrdinalIgnoreCase) || |
||||
|
methodName.StartsWith("Create", StringComparison.OrdinalIgnoreCase) || |
||||
|
methodName.StartsWith("Insert", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
return "POST"; |
||||
|
} |
||||
|
|
||||
|
//Default
|
||||
|
return DefaultHttpVerb; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,141 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using Volo.Abp.Http.Modeling; |
||||
|
|
||||
|
namespace Volo.Abp.Http.ProxyScripting.Generators |
||||
|
{ |
||||
|
internal static class ProxyScriptingJsFuncHelper |
||||
|
{ |
||||
|
private const string ValidJsVariableNameChars = "abcdefghijklmnopqrstuxwvyzABCDEFGHIJKLMNOPQRSTUXWVYZ0123456789_"; |
||||
|
|
||||
|
private static readonly HashSet<string> ReservedWords = new HashSet<string> { |
||||
|
"abstract", |
||||
|
"else", |
||||
|
"instanceof", |
||||
|
"super", |
||||
|
"boolean", |
||||
|
"enum", |
||||
|
"int", |
||||
|
"switch", |
||||
|
"break", |
||||
|
"export", |
||||
|
"interface", |
||||
|
"synchronized", |
||||
|
"byte", |
||||
|
"extends", |
||||
|
"let", |
||||
|
"this", |
||||
|
"case", |
||||
|
"false", |
||||
|
"long", |
||||
|
"throw", |
||||
|
"catch", |
||||
|
"final", |
||||
|
"native", |
||||
|
"throws", |
||||
|
"char", |
||||
|
"finally", |
||||
|
"new", |
||||
|
"transient", |
||||
|
"class", |
||||
|
"float", |
||||
|
"null", |
||||
|
"true", |
||||
|
"const", |
||||
|
"for", |
||||
|
"package", |
||||
|
"try", |
||||
|
"continue", |
||||
|
"function", |
||||
|
"private", |
||||
|
"typeof", |
||||
|
"debugger", |
||||
|
"goto", |
||||
|
"protected", |
||||
|
"var", |
||||
|
"default", |
||||
|
"if", |
||||
|
"public", |
||||
|
"void", |
||||
|
"delete", |
||||
|
"implements", |
||||
|
"return", |
||||
|
"volatile", |
||||
|
"do", |
||||
|
"import", |
||||
|
"short", |
||||
|
"while", |
||||
|
"double", |
||||
|
"in", |
||||
|
"static", |
||||
|
"with" |
||||
|
}; |
||||
|
|
||||
|
public static string NormalizeJsVariableName(string name, string additionalChars = "") |
||||
|
{ |
||||
|
var validChars = ValidJsVariableNameChars + additionalChars; |
||||
|
|
||||
|
var sb = new StringBuilder(name); |
||||
|
|
||||
|
sb.Replace('-', '_'); |
||||
|
|
||||
|
//Delete invalid chars
|
||||
|
foreach (var c in name) |
||||
|
{ |
||||
|
if (!validChars.Contains(c)) |
||||
|
{ |
||||
|
sb.Replace(c.ToString(), ""); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (sb.Length == 0) |
||||
|
{ |
||||
|
return "_" + Guid.NewGuid().ToString("N").Left(8); |
||||
|
} |
||||
|
|
||||
|
return sb.ToString(); |
||||
|
} |
||||
|
|
||||
|
public static string WrapWithBracketsOrWithDotPrefix(string name) |
||||
|
{ |
||||
|
if (!ReservedWords.Contains(name)) |
||||
|
{ |
||||
|
return "." + name; |
||||
|
} |
||||
|
|
||||
|
return "['" + name + "']"; |
||||
|
} |
||||
|
|
||||
|
public static string GetParamNameInJsFunc(ParameterApiDescriptionModel parameterInfo) |
||||
|
{ |
||||
|
return parameterInfo.Name == parameterInfo.NameOnMethod |
||||
|
? NormalizeJsVariableName(parameterInfo.Name.ToCamelCase(), ".") |
||||
|
: NormalizeJsVariableName(parameterInfo.NameOnMethod.ToCamelCase()) + "." + NormalizeJsVariableName(parameterInfo.Name.ToCamelCase(), "."); |
||||
|
} |
||||
|
|
||||
|
public static string CreateJsObjectLiteral(ParameterApiDescriptionModel[] parameters, int indent = 0) |
||||
|
{ |
||||
|
var sb = new StringBuilder(); |
||||
|
|
||||
|
sb.AppendLine("{"); |
||||
|
|
||||
|
foreach (var prm in parameters) |
||||
|
{ |
||||
|
sb.AppendLine($"{new string(' ', indent)} '{prm.Name}': {GetParamNameInJsFunc(prm)}"); |
||||
|
} |
||||
|
|
||||
|
sb.Append(new string(' ', indent) + "}"); |
||||
|
|
||||
|
return sb.ToString(); |
||||
|
} |
||||
|
|
||||
|
public static string GenerateJsFuncParameterList(ActionApiDescriptionModel action, string ajaxParametersName) |
||||
|
{ |
||||
|
var methodParamNames = action.Parameters.Select(p => p.NameOnMethod).Distinct().ToList(); |
||||
|
methodParamNames.Add(ajaxParametersName); |
||||
|
return methodParamNames.Select(prmName => NormalizeJsVariableName(prmName.ToCamelCase())).JoinAsString(", "); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace Volo.Abp.Http.ProxyScripting |
||||
|
{ |
||||
|
public interface IProxyScriptManager |
||||
|
{ |
||||
|
string GetScript(ProxyScriptingModel scriptingModel); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Concurrent; |
||||
|
using System.Collections.Generic; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Http.Modeling; |
||||
|
using Volo.Abp.Http.ProxyScripting.Configuration; |
||||
|
using Volo.Abp.Http.ProxyScripting.Generators; |
||||
|
using Volo.Abp.Json; |
||||
|
|
||||
|
namespace Volo.Abp.Http.ProxyScripting |
||||
|
{ |
||||
|
public class ProxyScriptManager : IProxyScriptManager, ISingletonDependency |
||||
|
{ |
||||
|
private readonly IApiDescriptionModelProvider _modelProvider; |
||||
|
private readonly AbpApiProxyScriptingOptions _options; |
||||
|
private readonly IServiceProvider _serviceProvider; |
||||
|
private readonly IJsonSerializer _jsonSerializer; |
||||
|
|
||||
|
private readonly ConcurrentDictionary<string, string> _cache; |
||||
|
|
||||
|
public ProxyScriptManager( |
||||
|
IApiDescriptionModelProvider modelProvider, |
||||
|
IOptions<AbpApiProxyScriptingOptions> options, |
||||
|
IServiceProvider serviceProvider, |
||||
|
IJsonSerializer jsonSerializer) |
||||
|
{ |
||||
|
_modelProvider = modelProvider; |
||||
|
_options = options.Value; |
||||
|
_serviceProvider = serviceProvider; |
||||
|
_jsonSerializer = jsonSerializer; |
||||
|
|
||||
|
_cache = new ConcurrentDictionary<string, string>(); |
||||
|
} |
||||
|
|
||||
|
public string GetScript(ProxyScriptingModel scriptingModel) |
||||
|
{ |
||||
|
if (scriptingModel.UseCache) |
||||
|
{ |
||||
|
return _cache.GetOrAdd(CreateCacheKey(scriptingModel), (key) => CreateScript(scriptingModel)); |
||||
|
} |
||||
|
|
||||
|
return _cache[CreateCacheKey(scriptingModel)] = CreateScript(scriptingModel); |
||||
|
} |
||||
|
|
||||
|
private string CreateScript(ProxyScriptingModel scriptingModel) |
||||
|
{ |
||||
|
var apiModel = _modelProvider.CreateApiModel(); |
||||
|
|
||||
|
if (scriptingModel.IsPartialRequest()) |
||||
|
{ |
||||
|
apiModel = apiModel.CreateSubModel(scriptingModel.Modules, scriptingModel.Controllers, scriptingModel.Actions); |
||||
|
} |
||||
|
|
||||
|
var generatorType = _options.Generators.GetOrDefault(scriptingModel.GeneratorType); |
||||
|
if (generatorType == null) |
||||
|
{ |
||||
|
throw new AbpException($"Could not find a proxy script generator with given name: {scriptingModel.GeneratorType}"); |
||||
|
} |
||||
|
|
||||
|
using (var scope = _serviceProvider.CreateScope()) |
||||
|
{ |
||||
|
return scope.ServiceProvider.GetRequiredService(generatorType).As<IProxyScriptGenerator>().CreateScript(apiModel); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private string CreateCacheKey(ProxyScriptingModel model) |
||||
|
{ |
||||
|
return _jsonSerializer.Serialize(model).ToMd5(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.Http.ProxyScripting |
||||
|
{ |
||||
|
public class ProxyScriptingModel |
||||
|
{ |
||||
|
public string GeneratorType { get; set; } |
||||
|
|
||||
|
public bool UseCache { get; set; } |
||||
|
|
||||
|
public string[] Modules { get; set; } |
||||
|
|
||||
|
public string[] Controllers { get; set; } |
||||
|
|
||||
|
public string[] Actions { get; set; } |
||||
|
|
||||
|
public IDictionary<string, string> Properties { get; set; } |
||||
|
|
||||
|
public ProxyScriptingModel(string generatorType, bool useCache = true) |
||||
|
{ |
||||
|
GeneratorType = generatorType; |
||||
|
UseCache = useCache; |
||||
|
|
||||
|
Properties = new Dictionary<string, string>(); |
||||
|
} |
||||
|
|
||||
|
public bool IsPartialRequest() |
||||
|
{ |
||||
|
return !(Modules.IsNullOrEmpty() && Controllers.IsNullOrEmpty() && Actions.IsNullOrEmpty()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Shouldly; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.ProxyScripting |
||||
|
{ |
||||
|
public class AbpServiceProxiesController_Tests : AspNetCoreMvcTestBase |
||||
|
{ |
||||
|
[Fact] |
||||
|
public async Task GetAll() |
||||
|
{ |
||||
|
var script = await GetResponseAsStringAsync("/AbpServiceProxies/GetAll"); |
||||
|
script.Length.ShouldBeGreaterThan(0); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue