Skip to content

Commit 8e3e131

Browse files
committed
mvc integration
1 parent eee81df commit 8e3e131

9 files changed

Lines changed: 616 additions & 0 deletions
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) Arjen Post. See License.txt and Notice.txt in the project root for license information.
2+
3+
using System;
4+
using Newtonsoft.Json;
5+
6+
namespace Microsoft.AspNetCore.Mvc
7+
{
8+
public static class ControllerExtensions
9+
{
10+
/// <summary>
11+
/// Creates a <see cref="PartialJsonResult"/> object that serializes the specified <paramref name="data"/> object
12+
/// to JSON.
13+
/// </summary>
14+
/// <param name="controller">The controller instance.</param>
15+
/// <param name="data">The object to serialize.</param>
16+
/// <returns>The created <see cref="PartialJsonResult"/> that serializes the specified <paramref name="data"/>
17+
/// to JSON format for the response.</returns>
18+
public static PartialJsonResult PartialJson(this ControllerBase controller, object data)
19+
{
20+
if (controller == null)
21+
{
22+
throw new ArgumentNullException(nameof(controller));
23+
}
24+
25+
return new PartialJsonResult(data);
26+
}
27+
28+
/// <summary>
29+
/// Creates a <see cref="PartialJsonResult"/> object that serializes the specified <paramref name="data"/> object
30+
/// to JSON.
31+
/// </summary>
32+
/// <param name="controller">The controller instance.</param>
33+
/// <param name="data">The object to serialize.</param>
34+
/// <param name="serializerSettings">The <see cref="JsonSerializerSettings"/> to be used by
35+
/// the formatter.</param>
36+
/// <returns>The created <see cref="PartialJsonResult"/> that serializes the specified <paramref name="data"/>
37+
/// as JSON format for the response.</returns>
38+
/// <remarks>Callers should cache an instance of <see cref="JsonSerializerSettings"/> to avoid
39+
/// recreating cached data with each call.</remarks>
40+
public static PartialJsonResult PartialJson(this ControllerBase controller, object data, JsonSerializerSettings serializerSettings)
41+
{
42+
if (controller == null)
43+
{
44+
throw new ArgumentNullException(nameof(controller));
45+
}
46+
47+
if (serializerSettings == null)
48+
{
49+
throw new ArgumentNullException(nameof(serializerSettings));
50+
}
51+
52+
return new PartialJsonResult(data, serializerSettings);
53+
}
54+
}
55+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright (c) Arjen Post. See License.txt and Notice.txt in the project root for license information.
2+
3+
using System;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.DependencyInjection.Extensions;
7+
using Microsoft.Extensions.Options;
8+
using Newtonsoft.Json;
9+
using PartialResponse.AspNetCore.Mvc;
10+
using PartialResponse.AspNetCore.Mvc.Formatters.Json.Internal;
11+
12+
namespace PartialResponse.Extensions.DependencyInjection
13+
{
14+
public static class MvcPartialJsonMvcBuilderExtensions
15+
{
16+
public static IMvcBuilder AddPartialJsonFormatters(this IMvcBuilder builder)
17+
{
18+
if (builder == null)
19+
{
20+
throw new ArgumentNullException(nameof(builder));
21+
}
22+
23+
AddPartialJsonFormatterServices(builder.Services);
24+
return builder;
25+
}
26+
27+
public static IMvcBuilder AddPartialJsonFormatters(
28+
this IMvcBuilder builder,
29+
Action<JsonSerializerSettings> setupAction)
30+
{
31+
if (builder == null)
32+
{
33+
throw new ArgumentNullException(nameof(builder));
34+
}
35+
36+
if (setupAction == null)
37+
{
38+
throw new ArgumentNullException(nameof(setupAction));
39+
}
40+
41+
AddPartialJsonFormatterServices(builder.Services);
42+
43+
builder.Services.Configure<MvcPartialJsonOptions>((options) => setupAction(options.SerializerSettings));
44+
45+
return builder;
46+
}
47+
48+
/// <summary>
49+
/// Adds configuration of <see cref="MvcPartialJsonOptions"/> for the application.
50+
/// </summary>
51+
/// <param name="builder">The <see cref="IMvcBuilder"/>.</param>
52+
/// <param name="setupAction">The <see cref="MvcPartialJsonOptions"/> which need to be configured.</param>
53+
/// <returns>The <see cref="IMvcBuilder"/>.</returns>
54+
public static IMvcBuilder AddPartialJsonOptions(
55+
this IMvcBuilder builder,
56+
Action<MvcPartialJsonOptions> setupAction)
57+
{
58+
if (builder == null)
59+
{
60+
throw new ArgumentNullException(nameof(builder));
61+
}
62+
63+
if (setupAction == null)
64+
{
65+
throw new ArgumentNullException(nameof(setupAction));
66+
}
67+
68+
builder.Services.Configure<MvcPartialJsonOptions>(setupAction);
69+
return builder;
70+
}
71+
72+
// Internal for testing.
73+
internal static void AddPartialJsonFormatterServices(IServiceCollection services)
74+
{
75+
services.TryAddEnumerable(
76+
ServiceDescriptor.Transient<IConfigureOptions<MvcOptions>, MvcPartialJsonMvcOptionsSetup>());
77+
services.TryAddSingleton<PartialJsonResultExecutor>();
78+
}
79+
}
80+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright (c) Arjen Post. See License.txt and Notice.txt in the project root for license information.
2+
3+
using System;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.DependencyInjection.Extensions;
7+
using Microsoft.Extensions.Options;
8+
using Newtonsoft.Json;
9+
using PartialResponse.AspNetCore.Mvc;
10+
using PartialResponse.AspNetCore.Mvc.Formatters.Json.Internal;
11+
12+
namespace PartialResponse.Extensions.DependencyInjection
13+
{
14+
public static class MvcPartialJsonMvcCoreBuilderExtensions
15+
{
16+
public static IMvcCoreBuilder AddPartialJsonFormatters(this IMvcCoreBuilder builder)
17+
{
18+
if (builder == null)
19+
{
20+
throw new ArgumentNullException(nameof(builder));
21+
}
22+
23+
AddPartialJsonFormatterServices(builder.Services);
24+
return builder;
25+
}
26+
27+
public static IMvcCoreBuilder AddPartialJsonFormatters(
28+
this IMvcCoreBuilder builder,
29+
Action<JsonSerializerSettings> setupAction)
30+
{
31+
if (builder == null)
32+
{
33+
throw new ArgumentNullException(nameof(builder));
34+
}
35+
36+
if (setupAction == null)
37+
{
38+
throw new ArgumentNullException(nameof(setupAction));
39+
}
40+
41+
AddPartialJsonFormatterServices(builder.Services);
42+
43+
builder.Services.Configure<MvcPartialJsonOptions>((options) => setupAction(options.SerializerSettings));
44+
45+
return builder;
46+
}
47+
48+
/// <summary>
49+
/// Adds configuration of <see cref="MvcPartialJsonOptions"/> for the application.
50+
/// </summary>
51+
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
52+
/// <param name="setupAction">The <see cref="MvcPartialJsonOptions"/> which need to be configured.</param>
53+
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
54+
public static IMvcCoreBuilder AddPartialJsonOptions(
55+
this IMvcCoreBuilder builder,
56+
Action<MvcPartialJsonOptions> setupAction)
57+
{
58+
if (builder == null)
59+
{
60+
throw new ArgumentNullException(nameof(builder));
61+
}
62+
63+
if (setupAction == null)
64+
{
65+
throw new ArgumentNullException(nameof(setupAction));
66+
}
67+
68+
builder.Services.Configure<MvcPartialJsonOptions>(setupAction);
69+
return builder;
70+
}
71+
72+
// Internal for testing.
73+
internal static void AddPartialJsonFormatterServices(IServiceCollection services)
74+
{
75+
services.TryAddEnumerable(
76+
ServiceDescriptor.Transient<IConfigureOptions<MvcOptions>, MvcPartialJsonMvcOptionsSetup>());
77+
services.TryAddSingleton<PartialJsonResultExecutor>();
78+
}
79+
}
80+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) Arjen Post. See License.txt and Notice.txt in the project root for license information.
2+
3+
using System;
4+
using Microsoft.Extensions.Logging;
5+
6+
namespace PartialResponse.AspNetCore.Mvc.Formatters.Json.Internal
7+
{
8+
internal static class MvcPartialJsonLoggerExtensions
9+
{
10+
private static readonly Action<ILogger, string, Exception> _partialJsonResultExecuting;
11+
12+
static MvcPartialJsonLoggerExtensions()
13+
{
14+
_partialJsonResultExecuting = LoggerMessage.Define<string>(
15+
LogLevel.Information,
16+
1,
17+
"Executing PartialJsonResult, writing value {Value}.");
18+
}
19+
20+
public static void PartialJsonResultExecuting(this ILogger logger, object value)
21+
{
22+
_partialJsonResultExecuting(logger, Convert.ToString(value), null);
23+
}
24+
}
25+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright (c) Arjen Post. See License.txt and Notice.txt in the project root for license information.
2+
3+
using System;
4+
using System.Buffers;
5+
using Microsoft.AspNetCore.Mvc;
6+
using Microsoft.AspNetCore.Mvc.ModelBinding;
7+
using Microsoft.Extensions.Logging;
8+
using Microsoft.Extensions.ObjectPool;
9+
using Microsoft.Extensions.Options;
10+
using Microsoft.Net.Http.Headers;
11+
using Newtonsoft.Json;
12+
using Newtonsoft.Json.Linq;
13+
14+
namespace PartialResponse.AspNetCore.Mvc.Formatters.Json.Internal
15+
{
16+
/// <summary>
17+
/// Sets up JSON formatter options for <see cref="MvcOptions"/>.
18+
/// </summary>
19+
public class MvcPartialJsonMvcOptionsSetup : IConfigureOptions<MvcOptions>
20+
{
21+
private readonly ILoggerFactory _loggerFactory;
22+
private readonly JsonSerializerSettings _jsonSerializerSettings;
23+
private readonly ArrayPool<char> _charPool;
24+
private readonly ObjectPoolProvider _objectPoolProvider;
25+
26+
public MvcPartialJsonMvcOptionsSetup(
27+
ILoggerFactory loggerFactory,
28+
IOptions<MvcPartialJsonOptions> partialJsonOptions,
29+
ArrayPool<char> charPool,
30+
ObjectPoolProvider objectPoolProvider)
31+
{
32+
if (loggerFactory == null)
33+
{
34+
throw new ArgumentNullException(nameof(loggerFactory));
35+
}
36+
37+
if (partialJsonOptions == null)
38+
{
39+
throw new ArgumentNullException(nameof(partialJsonOptions));
40+
}
41+
42+
if (charPool == null)
43+
{
44+
throw new ArgumentNullException(nameof(charPool));
45+
}
46+
47+
if (objectPoolProvider == null)
48+
{
49+
throw new ArgumentNullException(nameof(objectPoolProvider));
50+
}
51+
52+
_loggerFactory = loggerFactory;
53+
_jsonSerializerSettings = partialJsonOptions.Value.SerializerSettings;
54+
_charPool = charPool;
55+
_objectPoolProvider = objectPoolProvider;
56+
}
57+
58+
public void Configure(MvcOptions options)
59+
{
60+
options.OutputFormatters.Add(new PartialJsonOutputFormatter(_jsonSerializerSettings, _charPool));
61+
62+
// TODO: Remove?
63+
options.FormatterMappings.SetMediaTypeMappingForFormat("json", MediaTypeHeaderValue.Parse("application/json"));
64+
65+
// TODO: Remove?
66+
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(JToken)));
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)