Api: added CustomJsonOptionsWrapper. optimization
This commit is contained in:
parent
f9329d81ba
commit
a26d8d24ce
@ -7,6 +7,10 @@
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview8.19405.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
|
||||
<ProjectReference Include="..\ASC.Common\ASC.Common.csproj" />
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ASC.Core;
|
||||
using ASC.Core.Tenants;
|
||||
@ -36,7 +35,6 @@ namespace ASC.Api.Core
|
||||
public class ApiContext : ICloneable
|
||||
{
|
||||
public HttpContext HttpContext { get; set; }
|
||||
private IQueryCollection Query { get; set; }
|
||||
private Tenant tenant;
|
||||
public Tenant Tenant { get { return tenant ?? (tenant = CoreContext.TenantManager.GetCurrentTenant(HttpContext)); } }
|
||||
|
||||
@ -45,42 +43,38 @@ namespace ASC.Api.Core
|
||||
if (httpContext == null) return;
|
||||
HttpContext = httpContext;
|
||||
|
||||
if (HttpContext.Request.QueryString != null)
|
||||
{
|
||||
Query = HttpContext.Request.Query;
|
||||
}
|
||||
|
||||
Count = 0;
|
||||
var query = HttpContext.Request.Query;
|
||||
//Try parse values
|
||||
var count = GetRequestValue("count");
|
||||
var count = query.GetRequestValue("count");
|
||||
if (!string.IsNullOrEmpty(count) && ulong.TryParse(count, out var countParsed))
|
||||
{
|
||||
//Count specified and valid
|
||||
Count = (long)countParsed;
|
||||
}
|
||||
|
||||
var startIndex = GetRequestValue("startIndex");
|
||||
var startIndex = query.GetRequestValue("startIndex");
|
||||
if (startIndex != null && long.TryParse(startIndex, out var startIndexParsed))
|
||||
{
|
||||
StartIndex = Math.Max(0, startIndexParsed);
|
||||
SpecifiedStartIndex = StartIndex;
|
||||
}
|
||||
|
||||
var sortOrder = GetRequestValue("sortOrder");
|
||||
var sortOrder = query.GetRequestValue("sortOrder");
|
||||
if ("descending".Equals(sortOrder))
|
||||
{
|
||||
SortDescending = true;
|
||||
}
|
||||
|
||||
FilterToType = GetRequestValue("type");
|
||||
SortBy = GetRequestValue("sortBy");
|
||||
FilterBy = GetRequestValue("filterBy");
|
||||
FilterOp = GetRequestValue("filterOp");
|
||||
FilterValue = GetRequestValue("filterValue");
|
||||
FilterValues = GetRequestArray("filterValue");
|
||||
Fields = GetRequestArray("fields");
|
||||
FilterToType = query.GetRequestValue("type");
|
||||
SortBy = query.GetRequestValue("sortBy");
|
||||
FilterBy = query.GetRequestValue("filterBy");
|
||||
FilterOp = query.GetRequestValue("filterOp");
|
||||
FilterValue = query.GetRequestValue("filterValue");
|
||||
FilterValues = query.GetRequestArray("filterValue");
|
||||
Fields = query.GetRequestArray("fields");
|
||||
|
||||
var updatedSince = GetRequestValue("updatedSince");
|
||||
var updatedSince = query.GetRequestValue("updatedSince");
|
||||
if (updatedSince != null)
|
||||
{
|
||||
UpdatedSince = Convert.ToDateTime(updatedSince);
|
||||
@ -89,35 +83,6 @@ namespace ASC.Api.Core
|
||||
|
||||
public string[] Fields { get; set; }
|
||||
|
||||
private string[] GetRequestArray(string key)
|
||||
{
|
||||
if (Query != null)
|
||||
{
|
||||
var values = Query[key + "[]"];
|
||||
if (values.Count > 0)
|
||||
return values;
|
||||
|
||||
values = Query[key];
|
||||
if (values.Count > 0)
|
||||
{
|
||||
if (values.Count == 1) //If it's only one element
|
||||
{
|
||||
//Try split
|
||||
if (!string.IsNullOrEmpty(values[0]))
|
||||
return values[0].Split(',');
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetRequestValue(string key)
|
||||
{
|
||||
var reqArray = GetRequestArray(key);
|
||||
return reqArray?.FirstOrDefault();
|
||||
}
|
||||
|
||||
public string[] FilterValues { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@ -180,8 +145,6 @@ namespace ASC.Api.Core
|
||||
|
||||
public bool FromCache { get; set; }
|
||||
|
||||
private readonly List<Type> _knowntype = new List<Type>();
|
||||
|
||||
internal long SpecifiedCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
@ -228,25 +191,10 @@ namespace ASC.Api.Core
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void RegisterType(Type type)
|
||||
public ApiContext SetCount(int count)
|
||||
{
|
||||
if (!_knowntype.Contains(type))
|
||||
{
|
||||
_knowntype.Add(type);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterTypes(IEnumerable<Type> types)
|
||||
{
|
||||
_knowntype.AddRange(types);
|
||||
|
||||
}
|
||||
|
||||
internal IEnumerable<Type> GetKnownTypes()
|
||||
{
|
||||
return _knowntype.Distinct();
|
||||
HttpContext.Items[nameof(Count)] = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
@ -268,6 +216,38 @@ namespace ASC.Api.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static class QueryExtension
|
||||
{
|
||||
internal static string[] GetRequestArray(this IQueryCollection query, string key)
|
||||
{
|
||||
if (query != null)
|
||||
{
|
||||
var values = query[key + "[]"];
|
||||
if (values.Count > 0)
|
||||
return values;
|
||||
|
||||
values = query[key];
|
||||
if (values.Count > 0)
|
||||
{
|
||||
if (values.Count == 1) //If it's only one element
|
||||
{
|
||||
//Try split
|
||||
if (!string.IsNullOrEmpty(values[0]))
|
||||
return values[0].Split(',');
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string GetRequestValue(this IQueryCollection query, string key)
|
||||
{
|
||||
var reqArray = query.GetRequestArray(key);
|
||||
return reqArray?.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApiContextExtension
|
||||
{
|
||||
public static bool Check(this ApiContext context, string field)
|
||||
|
19
common/ASC.Api.Core/Core/CustomJsonOptionsWrapper.cs
Normal file
19
common/ASC.Api.Core/Core/CustomJsonOptionsWrapper.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace ASC.Api.Core.Core
|
||||
{
|
||||
public class CustomJsonOptionsWrapper : IConfigureOptions<MvcNewtonsoftJsonOptions>
|
||||
{
|
||||
readonly IHttpContextAccessor ServiceProvider;
|
||||
public CustomJsonOptionsWrapper(IHttpContextAccessor serviceProvider)
|
||||
{
|
||||
ServiceProvider = serviceProvider;
|
||||
}
|
||||
public void Configure(MvcNewtonsoftJsonOptions options)
|
||||
{
|
||||
options.SerializerSettings.ContractResolver = new ResponseContractResolver(ServiceProvider);
|
||||
}
|
||||
}
|
||||
}
|
@ -29,8 +29,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
@ -38,9 +36,9 @@ namespace ASC.Api.Core
|
||||
{
|
||||
public class ResponseContractResolver : DefaultContractResolver
|
||||
{
|
||||
public ServiceProvider Services { get; }
|
||||
public IHttpContextAccessor Services { get; }
|
||||
|
||||
public ResponseContractResolver(ServiceProvider services)
|
||||
public ResponseContractResolver(IHttpContextAccessor services)
|
||||
{
|
||||
Services = services;
|
||||
NamingStrategy = new CamelCaseNamingStrategy
|
||||
@ -82,11 +80,11 @@ namespace ASC.Api.Core
|
||||
}
|
||||
public class JsonStringConverter : JsonConverter
|
||||
{
|
||||
public ServiceProvider Services { get; }
|
||||
public IHttpContextAccessor HttpContextAccessor { get; }
|
||||
|
||||
public JsonStringConverter(ServiceProvider services)
|
||||
public JsonStringConverter(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
Services = services;
|
||||
HttpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
@ -101,8 +99,7 @@ namespace ASC.Api.Core
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
var httpContext = new ApiContext(Services.GetService<IHttpContextAccessor>().HttpContext);
|
||||
var fields = httpContext.Fields;
|
||||
var fields = HttpContextAccessor.HttpContext.Request.Query.GetRequestArray("fields");
|
||||
|
||||
if (fields != null)
|
||||
{
|
||||
|
@ -57,27 +57,34 @@ namespace ASC.Api.Core.Middleware
|
||||
[DataMember(EmitDefaultValue = false, Order = 3)]
|
||||
public object Response { get; set; }
|
||||
|
||||
protected internal SuccessApiResponse(HttpStatusCode statusCode, object response, long? total = null) : base(statusCode)
|
||||
protected internal SuccessApiResponse(HttpStatusCode statusCode, object response, long? total = null, int? count = null) : base(statusCode)
|
||||
{
|
||||
Status = 0;
|
||||
Response = response;
|
||||
Total = total;
|
||||
|
||||
if (response is List<object> list)
|
||||
if (count.HasValue)
|
||||
{
|
||||
Count = list.Count;
|
||||
}
|
||||
else if (response is IEnumerable<object> collection)
|
||||
{
|
||||
Count = collection.Count();
|
||||
}
|
||||
else if (response == null)
|
||||
{
|
||||
Count = 0;
|
||||
Count = count;
|
||||
}
|
||||
else
|
||||
{
|
||||
Count = 1;
|
||||
if (response is List<object> list)
|
||||
{
|
||||
Count = list.Count;
|
||||
}
|
||||
else if (response is IEnumerable<object> collection)
|
||||
{
|
||||
Count = collection.Count();
|
||||
}
|
||||
else if (response == null)
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Count = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ namespace ASC.Api.Core.Middleware
|
||||
if (context.Result is ObjectResult result)
|
||||
{
|
||||
context.HttpContext.Items.TryGetValue("TotalCount", out var total);
|
||||
result.Value = new SuccessApiResponse((HttpStatusCode)context.HttpContext.Response.StatusCode, result.Value, (long?)total);
|
||||
context.HttpContext.Items.TryGetValue("Count", out var count);
|
||||
result.Value = new SuccessApiResponse((HttpStatusCode)context.HttpContext.Response.StatusCode, result.Value, (long?)total, (int?)count);
|
||||
}
|
||||
|
||||
base.OnResultExecuting(context);
|
||||
|
@ -91,7 +91,7 @@ namespace ASC.Core.Caching
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<UserInfo> GetUsers(int tenant, bool isAdmin, EmployeeStatus? employeeStatus, List<List<Guid>> includeGroups, List<Guid> excludeGroups, EmployeeActivationStatus? activationStatus, string text, string sortBy, bool sortOrderAsc, long limit, long offset, out int total)
|
||||
public List<UserInfo> GetUsers(int tenant, bool isAdmin, EmployeeStatus? employeeStatus, List<List<Guid>> includeGroups, List<Guid> excludeGroups, EmployeeActivationStatus? activationStatus, string text, string sortBy, bool sortOrderAsc, long limit, long offset, out int total)
|
||||
{
|
||||
return service.GetUsers(tenant, isAdmin, employeeStatus, includeGroups, excludeGroups, activationStatus, text, sortBy, sortOrderAsc, limit, offset, out total);
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ namespace ASC.Core
|
||||
return users.ToArray();
|
||||
}
|
||||
|
||||
public IEnumerable<UserInfo> GetUsers(int tenantId, bool isAdmin, EmployeeStatus? employeeStatus, List<List<Guid>> includeGroups, List<Guid> excludeGroups, EmployeeActivationStatus? activationStatus, string text, string sortBy, bool sortOrderAsc, long limit, long offset, out int total)
|
||||
public List<UserInfo> GetUsers(int tenantId, bool isAdmin, EmployeeStatus? employeeStatus, List<List<Guid>> includeGroups, List<Guid> excludeGroups, EmployeeActivationStatus? activationStatus, string text, string sortBy, bool sortOrderAsc, long limit, long offset, out int total)
|
||||
{
|
||||
return userService.GetUsers(tenantId, isAdmin, employeeStatus, includeGroups, excludeGroups, activationStatus, text, sortBy, sortOrderAsc, limit, offset, out total);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ namespace ASC.Core
|
||||
{
|
||||
IDictionary<Guid, UserInfo> GetUsers(int tenant, DateTime from);
|
||||
|
||||
IEnumerable<UserInfo> GetUsers(int tenant, bool isAdmin,
|
||||
List<UserInfo> GetUsers(int tenant, bool isAdmin,
|
||||
EmployeeStatus? employeeStatus,
|
||||
List<List<Guid>> includeGroups,
|
||||
List<Guid> excludeGroups,
|
||||
|
@ -50,7 +50,7 @@ namespace ASC.Core.Data
|
||||
return ExecList(q).ConvertAll(ToUser).ToDictionary(u => u.ID);
|
||||
}
|
||||
|
||||
public IEnumerable<UserInfo> GetUsers(int tenant, bool isAdmin,
|
||||
public List<UserInfo> GetUsers(int tenant, bool isAdmin,
|
||||
EmployeeStatus? employeeStatus,
|
||||
List<List<Guid>> includeGroups,
|
||||
List<Guid> excludeGroups,
|
||||
|
@ -16,10 +16,6 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview8.19405.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\ASC.Api.Core\ASC.Api.Core.csproj" />
|
||||
|
@ -308,7 +308,8 @@ namespace ASC.Employee.Core.Controllers
|
||||
|
||||
var users = CoreContext.UserManager.GetUsers(Tenant.TenantId, isAdmin, employeeStatus, includeGroups, excludeGroups, activationStatus, ApiContext.FilterValue, ApiContext.SortBy, !ApiContext.SortDescending, ApiContext.Count, ApiContext.StartIndex, out var total);
|
||||
|
||||
ApiContext.SetTotalCount(total);
|
||||
ApiContext.SetTotalCount(total)
|
||||
.SetCount(users.Count);
|
||||
|
||||
return users;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
using ASC.Api.Core;
|
||||
using ASC.Api.Core.Core;
|
||||
using ASC.Api.Core.Middleware;
|
||||
@ -24,6 +23,7 @@ using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace ASC.People
|
||||
{
|
||||
@ -43,12 +43,10 @@ namespace ASC.People
|
||||
services.AddHttpContextAccessor();
|
||||
|
||||
services.AddControllers()
|
||||
.AddNewtonsoftJson(s =>
|
||||
{
|
||||
s.SerializerSettings.ContractResolver = new ResponseContractResolver(services.BuildServiceProvider());
|
||||
})
|
||||
.AddNewtonsoftJson()
|
||||
.AddXmlSerializerFormatters();
|
||||
|
||||
services.AddTransient<IConfigureOptions<MvcNewtonsoftJsonOptions>, CustomJsonOptionsWrapper>();
|
||||
|
||||
services.AddMemoryCache();
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview8.19405.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0-preview8.19405.4" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0-preview8-19413-06" />
|
||||
</ItemGroup>
|
||||
|
@ -10,6 +10,7 @@ using ASC.Data.Storage.Configuration;
|
||||
using ASC.MessagingSystem;
|
||||
using ASC.Web.Core;
|
||||
using ASC.Web.Studio.Core.Notify;
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
@ -22,6 +23,7 @@ using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace ASC.Web.Api
|
||||
{
|
||||
@ -39,13 +41,11 @@ namespace ASC.Web.Api
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddControllers()
|
||||
.AddNewtonsoftJson(s =>
|
||||
{
|
||||
s.SerializerSettings.ContractResolver = new ResponseContractResolver(services.BuildServiceProvider());
|
||||
s.UseCamelCasing(true);
|
||||
})
|
||||
.AddNewtonsoftJson()
|
||||
.AddXmlSerializerFormatters();
|
||||
|
||||
services.AddTransient<IConfigureOptions<MvcNewtonsoftJsonOptions>, CustomJsonOptionsWrapper>();
|
||||
|
||||
services.AddMemoryCache();
|
||||
|
||||
services.AddDistributedMemoryCache();
|
||||
|
Loading…
Reference in New Issue
Block a user