mirror of https://github.com/abpframework/abp.git
39 changed files with 574 additions and 115 deletions
@ -0,0 +1,38 @@ |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc.Formatters; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Json.SystemTextJson; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Json |
|||
{ |
|||
public class AbpHybridJsonInputFormatter : TextInputFormatter, IInputFormatterExceptionPolicy |
|||
{ |
|||
public AbpHybridJsonInputFormatter() |
|||
{ |
|||
SupportedEncodings.Add(UTF8EncodingWithoutBOM); |
|||
SupportedEncodings.Add(UTF16EncodingLittleEndian); |
|||
|
|||
SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationJson); |
|||
SupportedMediaTypes.Add(MediaTypeHeaderValues.TextJson); |
|||
SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax); |
|||
} |
|||
|
|||
public async override Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) |
|||
{ |
|||
return await GetTextInputFormatter(context).ReadRequestBodyAsync(context, encoding); |
|||
} |
|||
|
|||
private TextInputFormatter GetTextInputFormatter(InputFormatterContext context) |
|||
{ |
|||
if (context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonSupportTypes>().CanHandle(context.ModelType)) |
|||
{ |
|||
return context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonInputFormatter>(); |
|||
} |
|||
|
|||
return context.HttpContext.RequestServices.GetRequiredService<NewtonsoftJsonInputFormatter>(); |
|||
} |
|||
|
|||
public InputFormatterExceptionPolicy ExceptionPolicy => InputFormatterExceptionPolicy.MalformedInputExceptions; |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc.Formatters; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Json.SystemTextJson; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Json |
|||
{ |
|||
public class AbpHybridJsonOutputFormatter : TextOutputFormatter |
|||
{ |
|||
public AbpHybridJsonOutputFormatter() |
|||
{ |
|||
SupportedEncodings.Add(Encoding.UTF8); |
|||
SupportedEncodings.Add(Encoding.Unicode); |
|||
SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationJson); |
|||
SupportedMediaTypes.Add(MediaTypeHeaderValues.TextJson); |
|||
SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyJsonSyntax); |
|||
} |
|||
|
|||
public async override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) |
|||
{ |
|||
await GetTextInputFormatter(context).WriteResponseBodyAsync(context, selectedEncoding); |
|||
} |
|||
|
|||
private TextOutputFormatter GetTextInputFormatter(OutputFormatterWriteContext context) |
|||
{ |
|||
if (context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonSupportTypes>().CanHandle(context.ObjectType)) |
|||
{ |
|||
return context.HttpContext.RequestServices.GetRequiredService<SystemTextJsonOutputFormatter>(); |
|||
} |
|||
|
|||
return context.HttpContext.RequestServices.GetRequiredService<NewtonsoftJsonOutputFormatter>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
using System; |
|||
using System.Reflection; |
|||
using Newtonsoft.Json; |
|||
using Newtonsoft.Json.Serialization; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Json.Newtonsoft; |
|||
using Volo.Abp.Reflection; |
|||
using Volo.Abp.Timing; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Json |
|||
{ |
|||
public class AbpMvcJsonContractResolver : DefaultContractResolver, ITransientDependency |
|||
{ |
|||
private readonly AbpJsonIsoDateTimeConverter _dateTimeConverter; |
|||
|
|||
public AbpMvcJsonContractResolver(AbpJsonIsoDateTimeConverter dateTimeConverter) |
|||
{ |
|||
_dateTimeConverter = dateTimeConverter; |
|||
|
|||
NamingStrategy = new CamelCaseNamingStrategy(); |
|||
} |
|||
|
|||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) |
|||
{ |
|||
var property = base.CreateProperty(member, memberSerialization); |
|||
|
|||
ModifyProperty(member, property); |
|||
|
|||
return property; |
|||
} |
|||
|
|||
protected virtual void ModifyProperty(MemberInfo member, JsonProperty property) |
|||
{ |
|||
if (property.PropertyType != typeof(DateTime) && property.PropertyType != typeof(DateTime?)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableDateTimeNormalizationAttribute>(member) == null) |
|||
{ |
|||
property.Converter = _dateTimeConverter; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Json |
|||
{ |
|||
public class AbpMvcNewtonsoftJsonOptionsSetup : IConfigureOptions<MvcNewtonsoftJsonOptions> |
|||
{ |
|||
protected IServiceProvider ServiceProvider { get; } |
|||
|
|||
public AbpMvcNewtonsoftJsonOptionsSetup(IServiceProvider serviceProvider) |
|||
{ |
|||
ServiceProvider = serviceProvider; |
|||
} |
|||
|
|||
public void Configure(MvcNewtonsoftJsonOptions options) |
|||
{ |
|||
options.SerializerSettings.ContractResolver = ServiceProvider.GetRequiredService<AbpMvcJsonContractResolver>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using Microsoft.Net.Http.Headers; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Json |
|||
{ |
|||
/// <summary>
|
|||
/// https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.NewtonsoftJson/src/MediaTypeHeaderValues.cs
|
|||
/// </summary>
|
|||
internal static class MediaTypeHeaderValues |
|||
{ |
|||
public static readonly MediaTypeHeaderValue ApplicationJson = MediaTypeHeaderValue.Parse("application/json").CopyAsReadOnly(); |
|||
|
|||
public static readonly MediaTypeHeaderValue TextJson = MediaTypeHeaderValue.Parse("text/json").CopyAsReadOnly(); |
|||
|
|||
public static readonly MediaTypeHeaderValue ApplicationAnyJsonSyntax = MediaTypeHeaderValue.Parse("application/*+json").CopyAsReadOnly(); |
|||
|
|||
public static readonly MediaTypeHeaderValue ApplicationXml = MediaTypeHeaderValue.Parse("application/xml").CopyAsReadOnly(); |
|||
|
|||
public static readonly MediaTypeHeaderValue TextXml = MediaTypeHeaderValue.Parse("text/xml").CopyAsReadOnly(); |
|||
|
|||
public static readonly MediaTypeHeaderValue ApplicationAnyXmlSyntax = MediaTypeHeaderValue.Parse("application/*+xml").CopyAsReadOnly(); |
|||
} |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
using System.Buffers; |
|||
using System.Text.Json; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Formatters; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Microsoft.Extensions.Options; |
|||
using System.Text.Encodings.Web; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.ObjectPool; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Json |
|||
{ |
|||
public static class MvcCoreBuilderExtensions |
|||
{ |
|||
public static IMvcCoreBuilder AddAbpHybridJson(this IMvcCoreBuilder builder) |
|||
{ |
|||
//SystemTextJsonInputFormatter
|
|||
builder.Services.AddTransient(provider => |
|||
{ |
|||
var jsonOptions = provider.GetRequiredService<IOptions<JsonOptions>>(); |
|||
var logger = provider.GetRequiredService<ILoggerFactory>().CreateLogger<SystemTextJsonInputFormatter>(); |
|||
return new SystemTextJsonInputFormatter(jsonOptions.Value, logger); |
|||
}); |
|||
|
|||
//NewtonsoftJsonInputFormatter
|
|||
builder.Services.AddTransient(provider => |
|||
{ |
|||
var jsonOptions = provider.GetRequiredService<IOptions<MvcNewtonsoftJsonOptions>>().Value; |
|||
|
|||
return new NewtonsoftJsonInputFormatter( |
|||
provider.GetRequiredService<ILoggerFactory>().CreateLogger<NewtonsoftJsonInputFormatter>(), |
|||
jsonOptions.SerializerSettings, |
|||
provider.GetRequiredService<ArrayPool<char>>(), |
|||
provider.GetRequiredService<DefaultObjectPoolProvider>(), |
|||
provider.GetRequiredService<IOptions<MvcOptions>>().Value, |
|||
jsonOptions); |
|||
}); |
|||
|
|||
//SystemTextJsonOutputFormatter
|
|||
builder.Services.AddTransient(provider => |
|||
{ |
|||
var jsonSerializerOptions = provider.GetRequiredService<IOptions<JsonOptions>>().Value.JsonSerializerOptions; |
|||
if (jsonSerializerOptions.Encoder is null) |
|||
{ |
|||
// If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters.
|
|||
jsonSerializerOptions = new JsonSerializerOptions(jsonSerializerOptions) |
|||
{ |
|||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, |
|||
}; |
|||
} |
|||
return new SystemTextJsonOutputFormatter(jsonSerializerOptions); |
|||
}); |
|||
|
|||
//NewtonsoftJsonOutputFormatter
|
|||
builder.Services.AddTransient(provider => |
|||
{ |
|||
var jsonOptions = provider.GetRequiredService<IOptions<MvcNewtonsoftJsonOptions>>().Value; |
|||
return new NewtonsoftJsonOutputFormatter( |
|||
jsonOptions.SerializerSettings, |
|||
provider.GetRequiredService<ArrayPool<char>>(), |
|||
provider.GetRequiredService<IOptions<MvcOptions>>().Value); |
|||
}); |
|||
|
|||
builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<JsonOptions>, AbpJsonOptionsSetup>()); |
|||
builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<MvcNewtonsoftJsonOptions>, AbpMvcNewtonsoftJsonOptionsSetup>()); |
|||
|
|||
builder.Services.Configure<MvcOptions>(options => |
|||
{ |
|||
options.InputFormatters.RemoveType<SystemTextJsonInputFormatter>(); |
|||
options.InputFormatters.RemoveType<NewtonsoftJsonInputFormatter>(); |
|||
options.InputFormatters.Add(new AbpHybridJsonInputFormatter()); |
|||
|
|||
options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>(); |
|||
options.OutputFormatters.RemoveType<NewtonsoftJsonOutputFormatter>(); |
|||
options.OutputFormatters.Add(new AbpHybridJsonOutputFormatter()); |
|||
}); |
|||
|
|||
return builder; |
|||
} |
|||
} |
|||
} |
|||
@ -1,3 +0,0 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -1,30 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -1,25 +0,0 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Json.Newtonsoft</AssemblyName> |
|||
<PackageId>Volo.Abp.Json.Newtonsoft</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Json\Volo.Abp.Json.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -1,21 +0,0 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.Json.Newtonsoft; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Json |
|||
{ |
|||
[DependsOn(typeof(AbpJsonModule))] |
|||
public class AbpJsonNewtonsoftModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpNewtonsoftJsonSerializerOptions>(options => |
|||
{ |
|||
options.Converters.Add<AbpJsonIsoDateTimeConverter>(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Json |
|||
{ |
|||
public class AbpHybridJsonSerializer : IJsonSerializer, ISingletonDependency |
|||
{ |
|||
private readonly Lazy<List<IJsonSerializerProvider>> _lazyProviders; |
|||
public List<IJsonSerializerProvider> Providers => _lazyProviders.Value; |
|||
|
|||
public AbpHybridJsonSerializer(IOptions<AbpJsonOptions> options, IServiceProvider serviceProvider) |
|||
{ |
|||
_lazyProviders = new Lazy<List<IJsonSerializerProvider>>( |
|||
() => options.Value |
|||
.Providers |
|||
.Select(c => serviceProvider.GetRequiredService(c) as IJsonSerializerProvider) |
|||
.Reverse() |
|||
.ToList(), |
|||
true |
|||
); |
|||
} |
|||
|
|||
public string Serialize(object obj, bool camelCase = true, bool indented = false) |
|||
{ |
|||
var provider = GetSerializerProvider(obj.GetType()); |
|||
return provider.Serialize(obj, camelCase, indented); |
|||
} |
|||
|
|||
public T Deserialize<T>(string jsonString, bool camelCase = true) |
|||
{ |
|||
var provider = GetSerializerProvider(typeof(T)); |
|||
return provider.Deserialize<T>(jsonString, camelCase); |
|||
} |
|||
|
|||
public object Deserialize(Type type, string jsonString, bool camelCase = true) |
|||
{ |
|||
var provider = GetSerializerProvider(type); |
|||
return provider.Deserialize(type, jsonString, camelCase); |
|||
} |
|||
|
|||
protected virtual IJsonSerializerProvider GetSerializerProvider(Type type) |
|||
{ |
|||
foreach (var provider in Providers.Where(provider => provider.CanHandle(type))) |
|||
{ |
|||
return provider; |
|||
} |
|||
|
|||
throw new AbpException($"There is no IJsonSerializerProvider that can handle {type.GetFullNameWithAssemblyName()} types!"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
|
|||
namespace Volo.Abp.Json |
|||
{ |
|||
public interface IJsonSerializerProvider |
|||
{ |
|||
bool CanHandle(Type type); |
|||
|
|||
string Serialize(object obj, bool camelCase = true, bool indented = false); |
|||
|
|||
T Deserialize<T>(string jsonString, bool camelCase = true); |
|||
|
|||
object Deserialize(Type type, string jsonString, bool camelCase = true); |
|||
} |
|||
} |
|||
@ -1,12 +1,12 @@ |
|||
using System.Text.Json; |
|||
|
|||
namespace Volo.Abp.Json |
|||
namespace Volo.Abp.Json.SystemTextJson |
|||
{ |
|||
public class AbpJsonSerializerOptions |
|||
public class AbpSystemTextJsonSerializerOptions |
|||
{ |
|||
public JsonSerializerOptions JsonSerializerOptions { get; } |
|||
|
|||
public AbpJsonSerializerOptions() |
|||
public AbpSystemTextJsonSerializerOptions() |
|||
{ |
|||
//TODO:Defaults?
|
|||
//https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Core/src/JsonOptions.cs#L18
|
|||
@ -1,20 +1,21 @@ |
|||
using System; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Json.JsonConverters; |
|||
using Volo.Abp.Json.SystemTextJson; |
|||
using Volo.Abp.Json.SystemTextJson.JsonConverters; |
|||
|
|||
namespace Volo.Abp.Json |
|||
{ |
|||
public class AbpJsonSerializerOptionsSetup : IConfigureOptions<AbpJsonSerializerOptions> |
|||
public class AbpSystemTextJsonSerializerOptionsSetup : IConfigureOptions<AbpSystemTextJsonSerializerOptions> |
|||
{ |
|||
protected IServiceProvider ServiceProvider { get; } |
|||
|
|||
public AbpJsonSerializerOptionsSetup(IServiceProvider serviceProvider) |
|||
public AbpSystemTextJsonSerializerOptionsSetup(IServiceProvider serviceProvider) |
|||
{ |
|||
ServiceProvider = serviceProvider; |
|||
} |
|||
|
|||
public void Configure(AbpJsonSerializerOptions options) |
|||
public void Configure(AbpSystemTextJsonSerializerOptions options) |
|||
{ |
|||
options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService<AbpDateTimeConverter>()); |
|||
options.JsonSerializerOptions.Converters.Add(ServiceProvider.GetRequiredService<AbpNullableDateTimeConverter>()); |
|||
@ -0,0 +1,62 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Reflection; |
|||
using Volo.Abp.Timing; |
|||
|
|||
namespace Volo.Abp.Json.SystemTextJson |
|||
{ |
|||
public class SystemTextJsonSupportTypes : ITransientDependency |
|||
{ |
|||
private static readonly List<Type> CacheTypes = new List<Type>(); |
|||
|
|||
private readonly SystemTextJsonSupportTypesOptions Options; |
|||
|
|||
public SystemTextJsonSupportTypes(IOptions<SystemTextJsonSupportTypesOptions> options) |
|||
{ |
|||
Options = options.Value; |
|||
} |
|||
|
|||
public bool CanHandle(Type type) |
|||
{ |
|||
if (CacheTypes.Any(x => x == type)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (type.GetCustomAttributes(true).Any(x => Options.IgnoreAttributes.Any(a => a == x.GetType()))) |
|||
{ |
|||
CacheTypes.Add(type); |
|||
return false; |
|||
} |
|||
|
|||
if (type.DeclaringType != null && type.DeclaringType.GetCustomAttributes(true).Any(x => Options.IgnoreAttributes.Any(a => a == x.GetType()))) |
|||
{ |
|||
CacheTypes.Add(type.DeclaringType); |
|||
return false; |
|||
} |
|||
|
|||
foreach (var propertyInfo in type.GetProperties()) |
|||
{ |
|||
if (propertyInfo.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true)) |
|||
{ |
|||
CacheTypes.Add(propertyInfo.GetType()); |
|||
return false; |
|||
} |
|||
|
|||
if (!TypeHelper.IsPrimitiveExtended(type)) |
|||
{ |
|||
if (!CanHandle(propertyInfo.PropertyType)) |
|||
{ |
|||
CacheTypes.Add(propertyInfo.PropertyType); |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using Volo.Abp.Collections; |
|||
|
|||
namespace Volo.Abp.Json.SystemTextJson |
|||
{ |
|||
public class SystemTextJsonSupportTypesOptions |
|||
{ |
|||
public ITypeList<Attribute> IgnoreAttributes; |
|||
|
|||
public SystemTextJsonSupportTypesOptions() |
|||
{ |
|||
IgnoreAttributes = new TypeList<Attribute>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.test.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Json\Volo.Abp.Json.csproj" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
|||
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.Testing; |
|||
|
|||
namespace Volo.Abp.Json |
|||
{ |
|||
public abstract class AbpJsonTestBase : AbpIntegratedTest<AbpJsonTestModule> |
|||
{ |
|||
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
|||
{ |
|||
options.UseAutofac(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Json |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpJsonModule), |
|||
typeof(AbpTestBaseModule) |
|||
)] |
|||
public class AbpJsonTestModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
using System; |
|||
using Shouldly; |
|||
using Volo.Abp.Json.SystemTextJson; |
|||
using Volo.Abp.Timing; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Json |
|||
{ |
|||
public class SystemTextJsonSupportTypes_Tests : AbpJsonTestBase |
|||
{ |
|||
private readonly SystemTextJsonSupportTypes _systemTextJsonSupportTypes; |
|||
|
|||
public SystemTextJsonSupportTypes_Tests() |
|||
{ |
|||
_systemTextJsonSupportTypes = GetRequiredService<SystemTextJsonSupportTypes>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Test() |
|||
{ |
|||
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass)).ShouldBeFalse(); |
|||
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass2)).ShouldBeFalse(); |
|||
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass3)).ShouldBeFalse(); |
|||
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass4)).ShouldBeFalse(); |
|||
|
|||
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass5)).ShouldBeTrue(); |
|||
_systemTextJsonSupportTypes.CanHandle(typeof(MyClass6)).ShouldBeTrue(); |
|||
} |
|||
|
|||
[DisableDateTimeNormalization] |
|||
class MyClass |
|||
{ |
|||
public DateTime Prop1 { get; set; } |
|||
} |
|||
|
|||
class MyClass2 |
|||
{ |
|||
[DisableDateTimeNormalization] |
|||
public DateTime Prop1 { get; set; } |
|||
} |
|||
|
|||
class MyClass3 |
|||
{ |
|||
public MyClass4 Prop1 { get; set; } |
|||
} |
|||
|
|||
class MyClass4 |
|||
{ |
|||
[DisableDateTimeNormalization] |
|||
public DateTime Prop1 { get; set; } |
|||
} |
|||
|
|||
class MyClass5 |
|||
{ |
|||
public DateTime Prop1 { get; set; } |
|||
|
|||
public MyClass6 Prop2 { get; set; } |
|||
} |
|||
|
|||
class MyClass6 |
|||
{ |
|||
public DateTime Prop1 { get; set; } |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue