diff --git a/src/Demo/Demo.csproj b/src/Demo/Demo.csproj
index 50e22bb..378c942 100644
--- a/src/Demo/Demo.csproj
+++ b/src/Demo/Demo.csproj
@@ -9,6 +9,8 @@
+
+
diff --git a/src/Demo/NewtonsoftSerializationProvider.cs b/src/Demo/NewtonsoftSerializationProvider.cs
new file mode 100644
index 0000000..5aea5ca
--- /dev/null
+++ b/src/Demo/NewtonsoftSerializationProvider.cs
@@ -0,0 +1,32 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
+
+namespace Demo;
+
+public class NewtonsoftSerializationProvider : IMultipartJsonSerializationProvider
+{
+ private readonly JsonSerializerSettings _serializerSettings;
+
+ public NewtonsoftSerializationProvider(IOptions options)
+ {
+ _serializerSettings = options.Value.SerializerSettings;
+ }
+
+ public NewtonsoftSerializationProvider()
+ {
+ _serializerSettings = new MvcNewtonsoftJsonOptions().SerializerSettings;
+ }
+
+ public string Serialize(object value)
+ {
+ return JsonConvert.SerializeObject(value, _serializerSettings);
+ }
+
+ public object Deserialize(ModelBindingContext bindingContext, string valueAsString)
+ {
+ return JsonConvert.DeserializeObject(valueAsString, bindingContext.ModelType, _serializerSettings)!;
+ }
+}
\ No newline at end of file
diff --git a/src/Demo/Program.cs b/src/Demo/Program.cs
index 1c26c79..ae29189 100644
--- a/src/Demo/Program.cs
+++ b/src/Demo/Program.cs
@@ -1,13 +1,14 @@
-using System.Xml;
+using Demo;
using Demo.Models.Products;
using FluentValidation;
using FluentValidation.AspNetCore;
using MicroElements.Swashbuckle.FluentValidation.AspNetCore;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Extensions;
-using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
-using Formatting=Newtonsoft.Json.Formatting;
var builder = WebApplication.CreateBuilder(args);
@@ -30,7 +31,7 @@
builder.Services.AddFluentValidationClientsideAdapters();
builder.Services.AddValidatorsFromAssemblyContaining();
ValidatorOptions.Global.LanguageManager.Enabled = false;
-builder.Services.AddJsonMultipartFormDataSupport(JsonSerializerChoice.Newtonsoft);
+builder.Services.AddJsonMultipartFormDataSupport();
builder.Services.AddSwaggerExamplesFromAssemblyOf();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
diff --git a/src/DemoOld/DemoOld.csproj b/src/DemoOld/DemoOld.csproj
index a96dbad..65326de 100644
--- a/src/DemoOld/DemoOld.csproj
+++ b/src/DemoOld/DemoOld.csproj
@@ -12,6 +12,8 @@
+
+
diff --git a/src/DemoOld/NewtonsoftSerializationProvider.cs b/src/DemoOld/NewtonsoftSerializationProvider.cs
new file mode 100644
index 0000000..3c09b44
--- /dev/null
+++ b/src/DemoOld/NewtonsoftSerializationProvider.cs
@@ -0,0 +1,33 @@
+using System;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
+
+namespace DemoOld;
+
+public class NewtonsoftSerializationProvider : IMultipartJsonSerializationProvider
+{
+ private readonly JsonSerializerSettings _serializerSettings;
+
+ public NewtonsoftSerializationProvider(IOptions options)
+ {
+ _serializerSettings = options.Value.SerializerSettings;
+ }
+
+ public NewtonsoftSerializationProvider()
+ {
+ _serializerSettings = new MvcNewtonsoftJsonOptions().SerializerSettings;
+ }
+
+ public string Serialize(object value)
+ {
+ return JsonConvert.SerializeObject(value, _serializerSettings);
+ }
+
+ public object Deserialize(ModelBindingContext bindingContext, string valueAsString)
+ {
+ return JsonConvert.DeserializeObject(valueAsString, bindingContext.ModelType, _serializerSettings)!;
+ }
+}
\ No newline at end of file
diff --git a/src/DemoOld/Startup.cs b/src/DemoOld/Startup.cs
index 0586afb..7d63948 100644
--- a/src/DemoOld/Startup.cs
+++ b/src/DemoOld/Startup.cs
@@ -11,72 +11,72 @@
using Newtonsoft.Json.Converters;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Extensions;
-using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
-namespace DemoOld {
- public class Startup {
- public Startup(IConfiguration configuration) {
- Configuration = configuration;
- }
+namespace DemoOld;
+
+public class Startup {
+ public Startup(IConfiguration configuration) {
+ Configuration = configuration;
+ }
- public IConfiguration Configuration { get; }
+ public IConfiguration Configuration { get; }
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services) {
- // ===== System.Text.Json =====
- // services.AddControllers()
- // .AddJsonOptions(options => {
- // options.JsonSerializerOptions.WriteIndented = true;
- // options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
- // });
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services) {
+ // ===== System.Text.Json =====
+ // services.AddControllers()
+ // .AddJsonOptions(options => {
+ // options.JsonSerializerOptions.WriteIndented = true;
+ // options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
+ // });
- // ===== JSON.Net- =====
- services.AddControllers()
- .AddNewtonsoftJson(options => {
- options.SerializerSettings.Converters.Add(new StringEnumConverter());
- options.SerializerSettings.Formatting = Formatting.Indented;
- })
- .AddFluentValidation(f => {
- f.RegisterValidatorsFromAssemblyContaining();
- // Important! Without this it won't work automatically
- // vvv
- f.ImplicitlyValidateChildProperties = true;
+ // ===== JSON.Net- =====
+ services.AddControllers()
+ .AddNewtonsoftJson(options => {
+ options.SerializerSettings.Converters.Add(new StringEnumConverter());
+ options.SerializerSettings.Formatting = Formatting.Indented;
+ })
+ .AddFluentValidation(f => {
+ f.RegisterValidatorsFromAssemblyContaining();
+ // Important! Without this it won't work automatically
+ // vvv
+ f.ImplicitlyValidateChildProperties = true;
- f.LocalizationEnabled = false;
- });
+ f.LocalizationEnabled = false;
+ });
- services.AddJsonMultipartFormDataSupport(JsonSerializerChoice.Newtonsoft);
- services.AddSwaggerExamplesFromAssemblyOf();
- services.AddSwaggerGen(o => {
- o.SwaggerDoc("v1", new OpenApiInfo {
- Title = "DemoOld",
- Version = "v1"
- });
+ // services.AddSingleton>(sp => new(new(sp.GetRequiredService>())));
+ services.AddJsonMultipartFormDataSupport();
+ services.AddSwaggerExamplesFromAssemblyOf();
+ services.AddSwaggerGen(o => {
+ o.SwaggerDoc("v1", new OpenApiInfo {
+ Title = "DemoOld",
+ Version = "v1"
});
- services.AddFluentValidationRulesToSwagger();
- }
+ });
+ services.AddFluentValidationRulesToSwagger();
+ }
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
- if (env.IsDevelopment()) {
- app.UseDeveloperExceptionPage();
- }
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
+ if (env.IsDevelopment()) {
+ app.UseDeveloperExceptionPage();
+ }
- app.UseSwagger();
- app.UseSwaggerUI(o => {
- o.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
- o.RoutePrefix = string.Empty;
- });
+ app.UseSwagger();
+ app.UseSwaggerUI(o => {
+ o.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
+ o.RoutePrefix = string.Empty;
+ });
- app.UseHttpsRedirection();
+ app.UseHttpsRedirection();
- app.UseRouting();
+ app.UseRouting();
- app.UseAuthorization();
+ app.UseAuthorization();
- app.UseEndpoints(endpoints => {
- endpoints.MapControllers();
- });
- }
+ app.UseEndpoints(endpoints => {
+ endpoints.MapControllers();
+ });
}
-}
+}
\ No newline at end of file
diff --git a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Extensions/MultipartFromDataServicesExtension.cs b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Extensions/MultipartFromDataServicesExtension.cs
index d16cf34..7b68e7e 100644
--- a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Extensions/MultipartFromDataServicesExtension.cs
+++ b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Extensions/MultipartFromDataServicesExtension.cs
@@ -1,7 +1,4 @@
-using System;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
+using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Extensions {
@@ -12,27 +9,27 @@ public static class MultipartFromDataServicesExtension {
///
/// Adds support for json in multipart/form-data requests
///
- public static IServiceCollection AddJsonMultipartFormDataSupport(this IServiceCollection services, JsonSerializerChoice jsonSerializerChoice) {
- JsonMultipartFormDataOptions.JsonSerializerChoice = jsonSerializerChoice;
-
- switch (jsonSerializerChoice) {
- case JsonSerializerChoice.SystemText:
- services.AddMvc(options => {
- var jsonOptions = services.BuildServiceProvider().GetRequiredService>();
- options.ModelBinderProviders.Insert(0, new FormDataJsonBinderProvider(jsonOptions));
- });
- break;
- case JsonSerializerChoice.Newtonsoft:
- services.AddMvc(options => {
- var jsonOptions = services.BuildServiceProvider().GetRequiredService>();
- options.ModelBinderProviders.Insert(0, new FormDataJsonBinderProvider(jsonOptions));
- });
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(jsonSerializerChoice), jsonSerializerChoice, null);
- }
-
+ public static IServiceCollection AddJsonMultipartFormDataSupport(this IServiceCollection services)
+ where TMultipartJsonSerializationProvider : class, IMultipartJsonSerializationProvider
+ {
+ services.AddSingleton();
+ return AddJsonMultipartFormDataSupport(services);
+ }
+
+ ///
+ /// Adds support for json in multipart/form-data requests
+ ///
+ public static IServiceCollection AddJsonMultipartFormDataSupport(this IServiceCollection services)
+ {
+ var serviceProvider = services.BuildServiceProvider();
+
+ var serializationProvider = serviceProvider.GetRequiredService();
+
+ services.AddMvc(options =>
+ {
+ options.ModelBinderProviders.Insert(0, new FormDataJsonBinderProvider(new(serializationProvider)));
+ });
services.AddSwaggerGen(options => {
options.OperationFilter();
diff --git a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/FormDataJsonBinderProvider.cs b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/FormDataJsonBinderProvider.cs
index 59e89b9..a8f49ea 100644
--- a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/FormDataJsonBinderProvider.cs
+++ b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/FormDataJsonBinderProvider.cs
@@ -1,9 +1,7 @@
using System;
using System.Reflection;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
-using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Attributes;
namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations {
@@ -11,18 +9,13 @@ namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations {
/// Looks for field with and use for binder.
///
public class FormDataJsonBinderProvider : IModelBinderProvider {
- private readonly IOptions _jsonOptions;
- private readonly IOptions _newtonSoftJsonOptions;
+ readonly JsonModelBinder _jsonModelBinder;
- public FormDataJsonBinderProvider(IOptions jsonOptions) {
- _jsonOptions = jsonOptions;
+ public FormDataJsonBinderProvider(JsonModelBinder jsonModelBinder)
+ {
+ _jsonModelBinder = jsonModelBinder;
}
-
-
- public FormDataJsonBinderProvider(IOptions newtonSoftJsonOptions) {
- _newtonSoftJsonOptions = newtonSoftJsonOptions;
- }
-
+
///
public IModelBinder GetBinder(ModelBinderProviderContext context) {
if (context == null) throw new ArgumentNullException(nameof(context));
@@ -42,13 +35,7 @@ public IModelBinder GetBinder(ModelBinderProviderContext context) {
// Do not use this provider if this property does not have the From attribute
if (propInfo.GetCustomAttribute() == null) return null;
- // All criteria met; use the FormDataJsonBinder
- if (_jsonOptions != null)
- return new JsonModelBinder(_jsonOptions);
- else if (_newtonSoftJsonOptions != null)
- return new JsonModelBinder(_newtonSoftJsonOptions);
- else
- return new JsonModelBinder();
+ return _jsonModelBinder;
}
}
}
\ No newline at end of file
diff --git a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/IMultipartJsonSerializationProvider.cs b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/IMultipartJsonSerializationProvider.cs
new file mode 100644
index 0000000..a76c185
--- /dev/null
+++ b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/IMultipartJsonSerializationProvider.cs
@@ -0,0 +1,12 @@
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+
+namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
+
+///
+/// Serialization provider for and .
+///
+public interface IMultipartJsonSerializationProvider
+{
+ public object Deserialize(ModelBindingContext bindingContext, string valueAsString);
+ public string Serialize(object value);
+}
\ No newline at end of file
diff --git a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonModelBinder.cs b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonModelBinder.cs
index 24a0c77..68fca28 100644
--- a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonModelBinder.cs
+++ b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonModelBinder.cs
@@ -1,100 +1,69 @@
using System;
using System.IO;
-using System.Text.Json;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
-using Microsoft.Extensions.Options;
-using Newtonsoft.Json;
-using JsonSerializer = System.Text.Json.JsonSerializer;
-namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations {
- ///
- /// Binds field from JSON string.
- ///
- public class JsonModelBinder : IModelBinder {
- private readonly IOptions _jsonOptions;
- private readonly IOptions _newtonsoftJsonOptions;
-
- public JsonModelBinder() { }
-
- public JsonModelBinder(IOptions jsonOptions) {
- _jsonOptions = jsonOptions;
+namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
+
+///
+/// Binds field from JSON string.
+///
+public class JsonModelBinder : IModelBinder {
+ readonly IMultipartJsonSerializationProvider _serializationProvider;
+
+ public JsonModelBinder(IMultipartJsonSerializationProvider serializationProvider) {
+ _serializationProvider = serializationProvider;
+ }
+
+ ///
+ public async Task BindModelAsync(ModelBindingContext bindingContext) {
+ if (bindingContext == null) {
+ throw new ArgumentNullException(nameof(bindingContext));
}
- public JsonModelBinder(IOptions newtonsoftJsonOptions) {
- _newtonsoftJsonOptions = newtonsoftJsonOptions;
+ string modelBindingKey;
+ if (bindingContext.IsTopLevelObject) {
+ modelBindingKey = bindingContext.BinderModelName;
+ }
+ else {
+ modelBindingKey = bindingContext.ModelName;
}
- ///
- public async Task BindModelAsync(ModelBindingContext bindingContext) {
- if (bindingContext == null) {
- throw new ArgumentNullException(nameof(bindingContext));
- }
-
- string modelBindingKey;
- if (bindingContext.IsTopLevelObject) {
- modelBindingKey = bindingContext.BinderModelName;
- }
- else {
- modelBindingKey = bindingContext.ModelName;
- }
-
- // Check the value sent in
- var valueProviderResult = await this.GetValueProvidedResult(bindingContext);
- if (valueProviderResult != ValueProviderResult.None) {
- bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
+ // Check the value sent in
+ var valueProviderResult = await this.GetValueProvidedResult(bindingContext);
+ if (valueProviderResult != ValueProviderResult.None) {
+ bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
- // Attempt to convert the input value
- var valueAsString = valueProviderResult.FirstValue;
+ // Attempt to convert the input value
+ var valueAsString = valueProviderResult.FirstValue;
- try {
- object result;
- if (_jsonOptions != null) {
- result = DeserializeUsingSystemSerializer(bindingContext, valueAsString);
- }
- else if (_newtonsoftJsonOptions != null) {
- result = DeserializeUsingJsonNet(bindingContext, valueAsString);
- }
- else {
- result = DeserializeUsingSystemSerializer(bindingContext, valueAsString);
- }
+ try {
+ var result = _serializationProvider.Deserialize(bindingContext, valueAsString);
- bindingContext.Result = ModelBindingResult.Success(result);
- }
- catch (Exception e) {
- bindingContext.ModelState.AddModelError(modelBindingKey ?? string.Empty, e.Message);
- }
+ bindingContext.Result = ModelBindingResult.Success(result);
+ }
+ catch (Exception e) {
+ bindingContext.ModelState.AddModelError(modelBindingKey ?? string.Empty, e.Message);
}
- }
-
- private object DeserializeUsingSystemSerializer(ModelBindingContext bindingContext, string valueAsString) {
- return JsonSerializer.Deserialize(valueAsString, bindingContext.ModelType,
- _jsonOptions?.Value?.JsonSerializerOptions ?? new JsonSerializerOptions());
}
+ }
- private object DeserializeUsingJsonNet(ModelBindingContext bindingContext, string valueAsString) {
- return JsonConvert.DeserializeObject(valueAsString, bindingContext.ModelType,
- _newtonsoftJsonOptions.Value.SerializerSettings);
+ private async Task GetValueProvidedResult(ModelBindingContext bindingContext) {
+ var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
+ if (valueProviderResult != ValueProviderResult.None) {
+ return valueProviderResult;
}
- private async Task GetValueProvidedResult(ModelBindingContext bindingContext) {
- var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
- if (valueProviderResult != ValueProviderResult.None) {
- return valueProviderResult;
- }
-
- var file = bindingContext.HttpContext.Request.Form.Files.GetFile(bindingContext.ModelName);
- if (file is null) {
- return valueProviderResult;
- }
+ var file = bindingContext.HttpContext.Request.Form.Files.GetFile(bindingContext.ModelName);
+ if (file is null) {
+ return valueProviderResult;
+ }
- await using var stream = file.OpenReadStream();
- using var reader = new StreamReader(stream);
- var json = await reader.ReadToEndAsync();
- valueProviderResult = new ValueProviderResult(json);
+ await using var stream = file.OpenReadStream();
+ using var reader = new StreamReader(stream);
+ var json = await reader.ReadToEndAsync();
+ valueProviderResult = new ValueProviderResult(json);
- return valueProviderResult;
- }
- }
+ return valueProviderResult;
+ }
}
\ No newline at end of file
diff --git a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonMultipartFormDataOptions.cs b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonMultipartFormDataOptions.cs
deleted file mode 100644
index c2798c3..0000000
--- a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonMultipartFormDataOptions.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations {
- internal static class JsonMultipartFormDataOptions {
- internal static JsonSerializerChoice JsonSerializerChoice = JsonSerializerChoice.SystemText;
- }
-}
\ No newline at end of file
diff --git a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonSerializerChoice.cs b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonSerializerChoice.cs
deleted file mode 100644
index 0c26dbd..0000000
--- a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/JsonSerializerChoice.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations {
- public enum JsonSerializerChoice {
- SystemText,
- Newtonsoft
- }
-}
\ No newline at end of file
diff --git a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/MultiPartJsonOperationFilter.cs b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/MultiPartJsonOperationFilter.cs
index a590681..b818ca5 100644
--- a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/MultiPartJsonOperationFilter.cs
+++ b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Integrations/MultiPartJsonOperationFilter.cs
@@ -2,17 +2,15 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
-using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
-using Newtonsoft.Json;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Attributes;
using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Extensions;
using Swashbuckle.AspNetCore.SwaggerGen;
-using JsonSerializer = System.Text.Json.JsonSerializer;
namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations
{
@@ -22,21 +20,17 @@ namespace Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations
public class MultiPartJsonOperationFilter : IOperationFilter
{
private readonly IServiceProvider _serviceProvider;
- private readonly IOptions _jsonOptions;
- private readonly IOptions _newtonsoftJsonOption;
private readonly IOptions _generatorOptions;
+ private readonly IMultipartJsonSerializationProvider _serializationResolver;
///
/// Creates
///
- public MultiPartJsonOperationFilter(IServiceProvider serviceProvider, IOptions jsonOptions,
- IOptions newtonsoftJsonOption,
- IOptions generatorOptions)
+ public MultiPartJsonOperationFilter(IServiceProvider serviceProvider, IOptions generatorOptions)
{
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
- _jsonOptions = jsonOptions;
- _newtonsoftJsonOption = newtonsoftJsonOption;
_generatorOptions = generatorOptions;
+ _serializationResolver = serviceProvider.GetRequiredService();
}
///
@@ -146,20 +140,13 @@ private static void AddEncoding(OpenApiMediaType mediaType, PropertyInfo propert
Explode = false
});
}
-
+
private void AddExample(PropertyInfo propertyInfo, OpenApiSchema openApiSchema)
{
var example = GetExampleFor(propertyInfo.PropertyType);
// Example do not exist. Use default.
if (example == null) return;
- string json;
-
- if (JsonMultipartFormDataOptions.JsonSerializerChoice == JsonSerializerChoice.SystemText)
- json = JsonSerializer.Serialize(example, _jsonOptions.Value.JsonSerializerOptions);
- else if (JsonMultipartFormDataOptions.JsonSerializerChoice == JsonSerializerChoice.Newtonsoft)
- json = JsonConvert.SerializeObject(example, _newtonsoftJsonOption.Value.SerializerSettings);
- else
- json = JsonSerializer.Serialize(example);
+ var json = _serializationResolver.Serialize(example);
openApiSchema.Example = new OpenApiString(json);
}
diff --git a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.csproj b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.csproj
index 913493c..5b0da42 100644
--- a/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.csproj
+++ b/src/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.csproj
@@ -18,7 +18,6 @@
-
diff --git a/src/tests/UnitTests/FormDataJsonBinderProviderTests.cs b/src/tests/UnitTests/FormDataJsonBinderProviderTests.cs
index 737f79f..eeb81ed 100644
--- a/src/tests/UnitTests/FormDataJsonBinderProviderTests.cs
+++ b/src/tests/UnitTests/FormDataJsonBinderProviderTests.cs
@@ -12,7 +12,7 @@ public class FormDataJsonBinderProviderTests {
public void GetBinder_ContextIsNull_ShouldThrowException() {
// Arrange
var options = Substitute.For>();
- var sut = new FormDataJsonBinderProvider(options);
+ var sut = new FormDataJsonBinderProvider(new(new JsonSerializationProvider(options)));
// Act
var action = () => sut.GetBinder(null!);
// Assert
@@ -26,7 +26,7 @@ public void GetBinder_ContextIsNull_ShouldThrowException() {
public void GetBinder_SimpleType_ShouldReturnNull(Type type) {
// Arrange
var options = Substitute.For>();
- var sut = new FormDataJsonBinderProvider(options);
+ var sut = new FormDataJsonBinderProvider(new(new JsonSerializationProvider(options)));
var context = new TestModelBinderProviderContext(new TestModelMetadata(ModelMetadataIdentity.ForType(type)));
// Act
var result = sut.GetBinder(context);
@@ -38,7 +38,7 @@ public void GetBinder_SimpleType_ShouldReturnNull(Type type) {
public void GetBinder_NotProperty_ShouldReturnNull() {
// Arrange
var options = Substitute.For>();
- var sut = new FormDataJsonBinderProvider(options);
+ var sut = new FormDataJsonBinderProvider(new(new JsonSerializationProvider(options)));
var context =
new TestModelBinderProviderContext(
new TestModelMetadata(ModelMetadataIdentity.ForType(typeof(TestTypeNoProperty))));
@@ -52,7 +52,7 @@ public void GetBinder_NotProperty_ShouldReturnNull() {
public void GetBinder_IFormFileProperty_ShouldReturnNull() {
// Arrange
var options = Substitute.For>();
- var sut = new FormDataJsonBinderProvider(options);
+ var sut = new FormDataJsonBinderProvider(new(new JsonSerializationProvider(options)));
var context =
TestModelBinderProviderContext.ForProperty(typeof(TestTypePropertyIFromFile), nameof(TestTypePropertyIFromFile.Test));
// Act
@@ -65,7 +65,7 @@ public void GetBinder_IFormFileProperty_ShouldReturnNull() {
public void GetBinder_PropertyWithoutFromJsonAttribute_ShouldReturnNull() {
// Arrange
var options = Substitute.For>();
- var sut = new FormDataJsonBinderProvider(options);
+ var sut = new FormDataJsonBinderProvider(new(new JsonSerializationProvider(options)));
var context =
TestModelBinderProviderContext.ForProperty(typeof(TestTypeNoAttribute), nameof(TestTypeNoAttribute.Test));
// Act
@@ -78,7 +78,7 @@ public void GetBinder_PropertyWithoutFromJsonAttribute_ShouldReturnNull() {
public void GetBinder_ShouldReturnJsonBinder() {
// Arrange
var options = Substitute.For>();
- var sut = new FormDataJsonBinderProvider(options);
+ var sut = new FormDataJsonBinderProvider(new(new JsonSerializationProvider(options)));
var context = TestModelBinderProviderContext.ForProperty(typeof(TestTypeContainer), nameof(TestTypeContainer.Test));
// Act
var result = sut.GetBinder(context);
diff --git a/src/tests/UnitTests/JsonModelBinderTests.cs b/src/tests/UnitTests/JsonModelBinderTests.cs
index ba94a3d..eb633ef 100644
--- a/src/tests/UnitTests/JsonModelBinderTests.cs
+++ b/src/tests/UnitTests/JsonModelBinderTests.cs
@@ -1,8 +1,8 @@
-using System.Text.Json;
-using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Primitives;
using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
using UnitTests.TestData.Types;
+using JsonSerializer = System.Text.Json.JsonSerializer;
namespace UnitTests;
@@ -10,7 +10,7 @@ public class JsonModelBinderTests {
[Test]
public void BindModelAsync_NullContext_ShouldReturnNull() {
// Arrange
- var sut = new JsonModelBinder();
+ var sut = new JsonModelBinder(new NewtonsoftSerializationProvider());
// Act
var action = async () => await sut.BindModelAsync(null!);
// Assert
@@ -20,7 +20,7 @@ public void BindModelAsync_NullContext_ShouldReturnNull() {
[Test]
public async Task BindModelAsync_ShouldBindData() {
// Arrange
- var sut = new JsonModelBinder();
+ var sut = new JsonModelBinder(new NewtonsoftSerializationProvider());
var testType = new TestType {
Id = 1,
Text = Guid.NewGuid().ToString()
diff --git a/src/tests/UnitTests/JsonSerializationProvider.cs b/src/tests/UnitTests/JsonSerializationProvider.cs
new file mode 100644
index 0000000..2de7287
--- /dev/null
+++ b/src/tests/UnitTests/JsonSerializationProvider.cs
@@ -0,0 +1,32 @@
+using System.Text.Json;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.Extensions.Options;
+using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
+
+namespace UnitTests;
+
+public class JsonSerializationProvider : IMultipartJsonSerializationProvider
+{
+ private readonly JsonSerializerOptions _serializerOptions;
+
+ public JsonSerializationProvider(IOptions options)
+ {
+ _serializerOptions = options.Value?.JsonSerializerOptions ?? new JsonOptions().JsonSerializerOptions;
+ }
+
+ public JsonSerializationProvider()
+ {
+ _serializerOptions = new JsonOptions().JsonSerializerOptions;
+ }
+
+ public string Serialize(object value)
+ {
+ return JsonSerializer.Serialize(value, _serializerOptions);
+ }
+
+ public object Deserialize(ModelBindingContext bindingContext, string valueAsString)
+ {
+ return JsonSerializer.Deserialize(valueAsString, bindingContext.ModelType, _serializerOptions)!;
+ }
+}
\ No newline at end of file
diff --git a/src/tests/UnitTests/NewtonsoftSerializationProvider.cs b/src/tests/UnitTests/NewtonsoftSerializationProvider.cs
new file mode 100644
index 0000000..7e3278d
--- /dev/null
+++ b/src/tests/UnitTests/NewtonsoftSerializationProvider.cs
@@ -0,0 +1,32 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using Swashbuckle.AspNetCore.JsonMultipartFormDataSupport.Integrations;
+
+namespace UnitTests;
+
+public class NewtonsoftSerializationProvider : IMultipartJsonSerializationProvider
+{
+ private readonly JsonSerializerSettings _serializerSettings;
+
+ public NewtonsoftSerializationProvider(IOptions options)
+ {
+ _serializerSettings = options.Value.SerializerSettings;
+ }
+
+ public NewtonsoftSerializationProvider()
+ {
+ _serializerSettings = new MvcNewtonsoftJsonOptions().SerializerSettings;
+ }
+
+ public string Serialize(object value)
+ {
+ return JsonConvert.SerializeObject(value, _serializerSettings);
+ }
+
+ public object Deserialize(ModelBindingContext bindingContext, string valueAsString)
+ {
+ return JsonConvert.DeserializeObject(valueAsString, bindingContext.ModelType, _serializerSettings)!;
+ }
+}
\ No newline at end of file
diff --git a/src/tests/UnitTests/UnitTests.csproj b/src/tests/UnitTests/UnitTests.csproj
index 6e4b5a3..80f40db 100644
--- a/src/tests/UnitTests/UnitTests.csproj
+++ b/src/tests/UnitTests/UnitTests.csproj
@@ -9,6 +9,7 @@
+