Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for custom serializers #83

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Refit/Attributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public override HttpMethod Method {
}

public enum BodySerializationMethod {
Json, UrlEncoded
Json, UrlEncoded, Custom
}

[AttributeUsage(AttributeTargets.Parameter)]
Expand Down
15 changes: 14 additions & 1 deletion Refit/RefitSettings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;

namespace Refit
{
Expand All @@ -7,9 +11,12 @@ public class RefitSettings
public RefitSettings()
{
UrlParameterFormatter = new DefaultUrlParameterFormatter();
CustomSerializers = new Dictionary<Type, ITypeSerializer>();
}

public IUrlParameterFormatter UrlParameterFormatter { get; set; }

public Dictionary<Type, ITypeSerializer> CustomSerializers { get; private set; }
}

public interface IUrlParameterFormatter
Expand All @@ -24,4 +31,10 @@ public virtual string Format(object parameterValue, ParameterInfo parameterInfo)
return parameterValue != null ? parameterValue.ToString() : null;
}
}

public interface ITypeSerializer
{
HttpContent SerializeAsHttpContent(object value);
Task<object> DeserializeFromHttpContent(HttpContent content);
}
}
23 changes: 20 additions & 3 deletions Refit/RequestBuilderImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ public Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(string me
ret.Content = new StringContent(stringParam);
} else {
switch (restMethod.BodyParameterInfo.Item1) {
case BodySerializationMethod.Custom:
var param = paramList[i];
ret.Content = settings.CustomSerializers[param.GetType()].SerializeAsHttpContent(param);
break;
case BodySerializationMethod.UrlEncoded:
ret.Content = new FormUrlEncodedContent(new FormValueDictionary(paramList[i]));
break;
Expand Down Expand Up @@ -230,6 +234,11 @@ Func<HttpClient, CancellationToken, object[], Task<T>> buildCancellableTaskFuncF
throw await ApiException.Create(resp);
}

ITypeSerializer customSerializer;
if (settings.CustomSerializers.TryGetValue(restMethod.SerializedReturnType, out customSerializer)) {
return (T)await customSerializer.DeserializeFromHttpContent(resp.Content);
}

var ms = new MemoryStream();
var fromStream = await resp.Content.ReadAsStreamAsync();
await fromStream.CopyToAsync(ms, 4096, ct);
Expand Down Expand Up @@ -317,6 +326,7 @@ public class RestMethodInfo
public Dictionary<int, ParameterInfo> ParameterInfoMap { get; set; }
public Type ReturnType { get; set; }
public Type SerializedReturnType { get; set; }
public RefitSettings RefitSettings { get; set; } // Placeholder until #80 is merged. How lazy am I!

static readonly Regex parameterRegex = new Regex(@"{(.*?)}");

Expand Down Expand Up @@ -413,8 +423,12 @@ string getUrlNameForParameter(ParameterInfo paramInfo)
Tuple<BodySerializationMethod, int> findBodyParameter(List<ParameterInfo> parameterList)
{
var bodyParams = parameterList
.Select(x => new { Parameter = x, BodyAttribute = x.GetCustomAttributes(true).OfType<BodyAttribute>().FirstOrDefault() })
.Where(x => x.BodyAttribute != null)
.Select(x => new {
Parameter = x,
BodyAttribute = x.GetCustomAttributes(true).OfType<BodyAttribute>().FirstOrDefault(),
HasCustomSerializer = RefitSettings.CustomSerializers.ContainsKey(x.ParameterType)
})
.Where(x => x.BodyAttribute != null || x.HasCustomSerializer)
.ToList();

if (bodyParams.Count > 1) {
Expand All @@ -426,7 +440,10 @@ Tuple<BodySerializationMethod, int> findBodyParameter(List<ParameterInfo> parame
}

var ret = bodyParams[0];
return Tuple.Create(ret.BodyAttribute.SerializationMethod, parameterList.IndexOf(ret.Parameter));
var serializationMethod = ret.HasCustomSerializer
? BodySerializationMethod.Custom
: ret.BodyAttribute.SerializationMethod;
return Tuple.Create(serializationMethod, parameterList.IndexOf(ret.Parameter));
}

Dictionary<string, string> parseHeaders(MethodInfo methodInfo)
Expand Down