Skip to content

Commit 63ac3fc

Browse files
committed
binders, body serializer, tests
1 parent d7bc688 commit 63ac3fc

27 files changed

+287
-92
lines changed

src/NetCoreStack.Proxy/Binders/BodyContentBinder.cs

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using Microsoft.AspNetCore.Http;
2-
using Newtonsoft.Json;
2+
using NetCoreStack.Contracts;
3+
using System;
34
using System.Collections.Generic;
45
using System.IO;
6+
using System.Linq;
57
using System.Net.Http;
68
using System.Net.Http.Headers;
79
using System.Text;
@@ -10,6 +12,14 @@ namespace NetCoreStack.Proxy
1012
{
1113
public abstract class BodyContentBinder : ContentModelBinder
1214
{
15+
protected IModelSerializer ModelSerializer { get; }
16+
17+
public BodyContentBinder(HttpMethod httpMethod, IModelSerializer modelSerializer)
18+
:base(httpMethod)
19+
{
20+
ModelSerializer = modelSerializer;
21+
}
22+
1323
protected virtual void AddFile(string key, MultipartFormDataContent multipartFormDataContent, IFormFile formFile)
1424
{
1525
using (var ms = new MemoryStream())
@@ -24,12 +34,21 @@ protected virtual void AddFile(string key, MultipartFormDataContent multipartFor
2434

2535
protected virtual byte[] Serialize(object value)
2636
{
27-
return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value));
37+
return Encoding.UTF8.GetBytes(ModelSerializer.Serialize(value));
2838
}
2939

30-
protected virtual StringContent SerializeToString(object value)
40+
protected virtual StringContent SerializeToString(ContentType contentType, ArraySegment<object> args)
3141
{
32-
return new StringContent(JsonConvert.SerializeObject(value), Encoding.UTF8, "application/json");
42+
var mediaType = "application/json";
43+
if (contentType == ContentType.Xml)
44+
mediaType = "application/xml";
45+
46+
if (args.Count == 1)
47+
{
48+
return new StringContent(ModelSerializer.Serialize(args.First()), Encoding.UTF8, mediaType);
49+
}
50+
51+
return new StringContent(ModelSerializer.Serialize(args), Encoding.UTF8, mediaType);
3352
}
3453

3554
protected virtual MultipartFormDataContent GetMultipartFormDataContent(ModelDictionaryResult contentResult)
@@ -51,5 +70,48 @@ protected virtual MultipartFormDataContent GetMultipartFormDataContent(ModelDict
5170
return multipartFormDataContent;
5271
}
5372

73+
protected virtual FormUrlEncodedContent GetUrlEncodedContent(ModelDictionaryResult contentResult)
74+
{
75+
FormUrlEncodedContent formUrlEncodedContent = new FormUrlEncodedContent(contentResult.Dictionary);
76+
return formUrlEncodedContent;
77+
}
78+
79+
public override void BindContent(ContentModelBindingContext bindingContext)
80+
{
81+
EnsureTemplateResult ensureTemplateResult = EnsureTemplate(bindingContext);
82+
if (ensureTemplateResult.BindingCompleted)
83+
return;
84+
85+
var parameterOffset = ensureTemplateResult.ParameterOffset;
86+
ModelDictionaryResult result = bindingContext.ModelContentResolver.Resolve(bindingContext.Parameters,
87+
bindingContext.Args,
88+
parameterOffset,
89+
ensureTemplateResult.IgnoreModelPrefix);
90+
91+
var contentType = bindingContext.ContentType;
92+
if (contentType == ContentType.MultipartFormData)
93+
{
94+
var content = GetMultipartFormDataContent(result);
95+
bindingContext.ContentResult = ContentModelBindingResult.Success(content);
96+
return;
97+
}
98+
99+
if (contentType == ContentType.FormUrlEncoded)
100+
{
101+
var content = GetUrlEncodedContent(result);
102+
bindingContext.ContentResult = ContentModelBindingResult.Success(content);
103+
return;
104+
}
105+
106+
var remainingParameterCount = bindingContext.ArgsLength - parameterOffset;
107+
if (remainingParameterCount <= 0)
108+
{
109+
// all parameters are resolved as Key - Url
110+
return;
111+
}
112+
113+
var segments = new ArraySegment<object>(bindingContext.Args, parameterOffset, remainingParameterCount);
114+
bindingContext.ContentResult = ContentModelBindingResult.Success(SerializeToString(contentType, segments));
115+
}
54116
}
55-
}
117+
}

src/NetCoreStack.Proxy/Binders/ContentBinderFactory.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,44 @@
1-
using System;
1+
using NetCoreStack.Contracts;
2+
using System;
23
using System.Net.Http;
4+
using Microsoft.Extensions.DependencyInjection;
35

46
namespace NetCoreStack.Proxy
57
{
68
public static class ContentBinderFactory
79
{
8-
public static IContentModelBinder GetContentModelBinder(HttpMethod httpMethod)
10+
public static IContentModelBinder GetContentModelBinder(IServiceProvider serviceProvider,
11+
HttpMethod httpMethod,
12+
ContentType contentType)
913
{
14+
IModelSerializer modelSerializer = null;
15+
if (contentType == ContentType.Xml)
16+
{
17+
modelSerializer = serviceProvider.GetService<IModelXmlSerializer>();
18+
}
19+
else
20+
{
21+
modelSerializer = serviceProvider.GetService<IModelJsonSerializer>();
22+
}
23+
1024
if (httpMethod == HttpMethod.Get)
1125
{
12-
return new HttpGetContentBinder();
26+
return new HttpGetContentBinder(httpMethod);
1327
}
1428

1529
if (httpMethod == HttpMethod.Post)
1630
{
17-
return new HttpPostContentBinder();
31+
return new HttpPostContentBinder(httpMethod, modelSerializer);
1832
}
1933

2034
if (httpMethod == HttpMethod.Put)
2135
{
22-
return new HttpPutContentBinder();
36+
return new HttpPutContentBinder(httpMethod, modelSerializer);
2337
}
2438

2539
if (httpMethod == HttpMethod.Delete)
2640
{
27-
return new HttpDeleteContentBinder();
41+
return new HttpDeleteContentBinder(httpMethod);
2842
}
2943

3044
throw new NotImplementedException($"{httpMethod.Method} is not supported or not implemented yet.");

src/NetCoreStack.Proxy/Types/ContentModelBinder.cs renamed to src/NetCoreStack.Proxy/Binders/ContentModelBinder.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
using System.Linq;
22
using System.Net;
3+
using System.Net.Http;
34

45
namespace NetCoreStack.Proxy
56
{
67
public abstract class ContentModelBinder : IContentModelBinder
78
{
9+
protected HttpMethod HttpMethod { get; }
10+
11+
public ContentModelBinder(HttpMethod httpMethod)
12+
{
13+
HttpMethod = httpMethod;
14+
}
15+
816
protected virtual EnsureTemplateResult EnsureTemplate(ContentModelBindingContext bindingContext)
917
{
1018
int parameterOffset = 0;

src/NetCoreStack.Proxy/Binders/HttpDeleteContentBinder.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ namespace NetCoreStack.Proxy
55
{
66
public class HttpDeleteContentBinder : ContentModelBinder
77
{
8-
HttpMethod HttpMethod => HttpMethod.Delete;
8+
public HttpDeleteContentBinder(HttpMethod httpMethod)
9+
:base(httpMethod)
10+
{
11+
12+
}
913

1014
public override void BindContent(ContentModelBindingContext bindingContext)
1115
{

src/NetCoreStack.Proxy/Binders/HttpGetContentBinder.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ namespace NetCoreStack.Proxy
55
{
66
public class HttpGetContentBinder : ContentModelBinder
77
{
8-
HttpMethod HttpMethod => HttpMethod.Get;
8+
public HttpGetContentBinder(HttpMethod httpMethod)
9+
: base(httpMethod)
10+
{
11+
12+
}
913

1014
public override void BindContent(ContentModelBindingContext bindingContext)
1115
{
@@ -17,7 +21,7 @@ public override void BindContent(ContentModelBindingContext bindingContext)
1721
bindingContext.Args,
1822
ensureTemplateResult.ParameterOffset,
1923
ensureTemplateResult.IgnoreModelPrefix);
20-
24+
2125
bindingContext.TryUpdateUri(result.Dictionary);
2226
}
2327
}

src/NetCoreStack.Proxy/Binders/HttpPostContentBinder.cs

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,15 @@ namespace NetCoreStack.Proxy
44
{
55
public class HttpPostContentBinder : BodyContentBinder
66
{
7-
HttpMethod HttpMethod => HttpMethod.Post;
7+
public HttpPostContentBinder(HttpMethod httpMethod, IModelSerializer modelSerializer)
8+
:base(httpMethod, modelSerializer)
9+
{
10+
11+
}
812

913
public override void BindContent(ContentModelBindingContext bindingContext)
1014
{
11-
EnsureTemplateResult ensureTemplateResult = EnsureTemplate(bindingContext);
12-
if (ensureTemplateResult.BindingCompleted)
13-
return;
14-
15-
ModelDictionaryResult result = bindingContext.ModelContentResolver.Resolve(bindingContext.Parameters,
16-
bindingContext.Args,
17-
ensureTemplateResult.ParameterOffset,
18-
ensureTemplateResult.IgnoreModelPrefix);
19-
20-
var isMultiPartFormData = bindingContext.IsMultiPartFormData;
21-
if (isMultiPartFormData)
22-
{
23-
var content = GetMultipartFormDataContent(result);
24-
bindingContext.ContentResult = ContentModelBindingResult.Success(content);
25-
return;
26-
}
27-
28-
if (bindingContext.ArgsLength == 1)
29-
{
30-
bindingContext.ContentResult = ContentModelBindingResult.Success(SerializeToString(bindingContext.Args[0]));
31-
return;
32-
}
33-
34-
bindingContext.ContentResult = ContentModelBindingResult.Success(SerializeToString(bindingContext.Args));
15+
base.BindContent(bindingContext);
3516
}
3617
}
3718
}

src/NetCoreStack.Proxy/Binders/HttpPutContentBinder.cs

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,15 @@ namespace NetCoreStack.Proxy
44
{
55
public class HttpPutContentBinder : BodyContentBinder
66
{
7-
HttpMethod HttpMethod => HttpMethod.Put;
8-
9-
public override void BindContent(ContentModelBindingContext bindingContext)
7+
public HttpPutContentBinder(HttpMethod httpMethod, IModelSerializer modelSerializer)
8+
: base(httpMethod, modelSerializer)
109
{
11-
EnsureTemplateResult ensureTemplateResult = EnsureTemplate(bindingContext);
12-
if (ensureTemplateResult.BindingCompleted)
13-
return;
14-
15-
ModelDictionaryResult result = bindingContext.ModelContentResolver.Resolve(bindingContext.Parameters,
16-
bindingContext.Args,
17-
ensureTemplateResult.ParameterOffset,
18-
ensureTemplateResult.IgnoreModelPrefix);
1910

20-
var isMultiPartFormData = bindingContext.IsMultiPartFormData;
21-
if (isMultiPartFormData)
22-
{
23-
var content = GetMultipartFormDataContent(result);
24-
bindingContext.ContentResult = ContentModelBindingResult.Success(content);
25-
return;
26-
}
11+
}
2712

28-
bindingContext.ContentResult = ContentModelBindingResult.Success(SerializeToString(result.Dictionary));
13+
public override void BindContent(ContentModelBindingContext bindingContext)
14+
{
15+
base.BindContent(bindingContext);
2916
}
3017
}
3118
}

src/NetCoreStack.Proxy/DefaultProxyContentStreamProvider.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
using NetCoreStack.Proxy.Extensions;
2+
using System;
23
using System.Net.Http;
34
using System.Threading.Tasks;
45

56
namespace NetCoreStack.Proxy
67
{
78
public class DefaultProxyContentStreamProvider : IProxyContentStreamProvider
89
{
10+
private readonly IServiceProvider _serviceProvider;
911
public ProxyMetadataProvider MetadataProvider { get; }
1012
public IModelContentResolver ContentResolver { get; }
1113

12-
public DefaultProxyContentStreamProvider(ProxyMetadataProvider metadataProvider, IModelContentResolver contentResolver)
14+
public DefaultProxyContentStreamProvider(IServiceProvider serviceProvider,
15+
ProxyMetadataProvider metadataProvider,
16+
IModelContentResolver contentResolver)
1317
{
18+
_serviceProvider = serviceProvider;
1419
MetadataProvider = metadataProvider;
1520
ContentResolver = contentResolver;
1621
}
@@ -23,12 +28,11 @@ public async Task CreateRequestContentAsync(RequestDescriptor requestContext,
2328
await Task.CompletedTask;
2429

2530
var httpMethod = descriptor.HttpMethod;
26-
var isMultiPartFormData = descriptor.IsMultiPartFormData;
27-
var contentModelBinder = ContentBinderFactory.GetContentModelBinder(httpMethod);
31+
var contentModelBinder = ContentBinderFactory.GetContentModelBinder(_serviceProvider, httpMethod, descriptor.ContentType);
2832

2933
var bindingContext = new ContentModelBindingContext(httpMethod, descriptor, proxyUriDefinition)
3034
{
31-
IsMultiPartFormData = isMultiPartFormData,
35+
ContentType = descriptor.ContentType,
3236
ModelContentResolver = ContentResolver,
3337
Args = requestContext.Args,
3438
};

src/NetCoreStack.Proxy/Extensions/ServiceCollectionExtensions.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static class ServiceCollectionExtensions
1515
typeof(ServiceCollectionExtensions).GetTypeInfo().GetDeclaredMethod("RegisterProxy");
1616

1717
public static void AddNetCoreProxy(this IServiceCollection services,
18-
IConfigurationRoot configuration,
18+
IConfiguration configuration,
1919
Action<ProxyBuilderOptions> setup)
2020
{
2121
services.AddOptions();
@@ -47,6 +47,8 @@ public static void AddNetCoreProxy(this IServiceCollection services,
4747
services.TryAdd(ServiceDescriptor.Singleton<IDefaultHeaderProvider, DefaultHeaderProvider>());
4848
services.TryAdd(ServiceDescriptor.Singleton<IProxyContentStreamProvider, DefaultProxyContentStreamProvider>());
4949
services.TryAdd(ServiceDescriptor.Singleton<IProxyEndpointManager, DefaultProxyEndpointManager>());
50+
services.TryAdd(ServiceDescriptor.Singleton<IModelJsonSerializer, DefaultModelJsonSerializer>());
51+
services.TryAdd(ServiceDescriptor.Singleton<IModelXmlSerializer, DefaultModelXmlSerializer>());
5052

5153
services.TryAddSingleton<RoundRobinManager>();
5254

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace NetCoreStack.Proxy
2+
{
3+
public interface IModelJsonSerializer : IModelSerializer
4+
{
5+
}
6+
}

0 commit comments

Comments
 (0)