Improve support for base64 strings

This commit is contained in:
Haacked
2014-12-30 17:50:11 -08:00
parent 543d1bb863
commit 641b03de41
4 changed files with 94 additions and 37 deletions
@@ -113,6 +113,18 @@ namespace Octokit.Tests
public string Content { get { return "*" + EncodedContent + "*"; } }
}
[Fact]
public void HandlesBase64EncodedStrings()
{
const string json = "{\"name\":\"RmVycmlzIEJ1ZWxsZXI=\",\"description\":\"stuff\",\"content\":\"RGF5IG9mZg==\"}";
var item = new SimpleJsonSerializer().Deserialize<SomeObject>(json);
Assert.Equal("Ferris Bueller", item.Name);
Assert.Equal("Day off", item.Content);
Assert.Equal("stuff", item.Description);
}
[Fact]
public void CanDeserializeOrganization()
{
+73 -8
View File
@@ -19,8 +19,6 @@ namespace Octokit
CanWrite = propertyInfo.CanWrite;
IsStatic = ReflectionUtils.GetGetterMethodInfo(propertyInfo).IsStatic;
IsPublic = ReflectionUtils.GetGetterMethodInfo(propertyInfo).IsPublic;
CanDeserialize = (IsPublic || HasParameterAttribute) && !IsStatic && CanWrite;
}
public PropertyOrField(FieldInfo fieldInfo) : this((MemberInfo)fieldInfo)
@@ -31,8 +29,6 @@ namespace Octokit
CanWrite = true;
IsStatic = fieldInfo.IsStatic;
IsPublic = fieldInfo.IsPublic;
CanDeserialize = (IsPublic || HasParameterAttribute) && !IsStatic && CanWrite && !fieldInfo.IsInitOnly;
}
protected PropertyOrField(MemberInfo memberInfo)
@@ -88,19 +84,74 @@ namespace Octokit
get { return MemberInfo.GetJsonFieldName(); }
}
public ReflectionUtils.GetDelegate GetDelegate
{
get
{
ReflectionUtils.GetDelegate getDelegate = null;
if (_propertyInfo != null)
{
getDelegate = ReflectionUtils.GetGetMethod(_propertyInfo);
}
if (_fieldInfo != null)
{
getDelegate = ReflectionUtils.GetGetMethod(_fieldInfo);
}
if (getDelegate == null)
{
throw new InvalidOperationException("Property and Field cannot both be null");
}
if (Base64Encoded)
{
return delegate(object source)
{
var value = getDelegate(source);
var stringValue = value as string;
if (stringValue == null)
{
return value;
}
return stringValue.ToBase64String();
};
}
return getDelegate;
}
}
public ReflectionUtils.SetDelegate SetDelegate
{
get
{
ReflectionUtils.SetDelegate setDelegate = null;
if (_propertyInfo != null)
{
return ReflectionUtils.GetSetMethod(_propertyInfo);
setDelegate = ReflectionUtils.GetSetMethod(_propertyInfo);
}
if (_fieldInfo != null)
{
return ReflectionUtils.GetSetMethod(_fieldInfo);
setDelegate = ReflectionUtils.GetSetMethod(_fieldInfo);
}
throw new InvalidOperationException("Property and Field cannot both be null");
if (setDelegate == null)
{
throw new InvalidOperationException("Property and Field cannot both be null");
}
if (Base64Encoded)
{
return delegate(object source, object value)
{
var stringValue = value as string;
if (stringValue == null)
{
setDelegate(source, value);
}
setDelegate(source, stringValue.FromBase64String());
};
}
return setDelegate;
}
}
@@ -120,6 +171,20 @@ namespace Octokit
}
}
public bool CanDeserialize { get; set; }
public bool CanDeserialize
{
get
{
return (IsPublic || HasParameterAttribute)
&& !IsStatic
&& CanWrite
&& (_fieldInfo == null || !_fieldInfo.IsInitOnly);
}
}
public bool CanSerialize
{
get { return IsPublic && CanRead && !IsStatic; }
}
}
}
-1
View File
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
+9 -28
View File
@@ -24,7 +24,6 @@ namespace Octokit.Internal
class GitHubSerializerStrategy : PocoJsonSerializerStrategy
{
readonly List<string> _membersWhichShouldPublishNull = new List<string>();
readonly List<string> _membersWhichShouldBeBase64Encoded = new List<string>();
protected override string MapClrMemberToJsonFieldName(MemberInfo member)
{
@@ -33,28 +32,19 @@ namespace Octokit.Internal
internal override IDictionary<string, ReflectionUtils.GetDelegate> GetterValueFactory(Type type)
{
var fullName = type.FullName + "-";
var propertiesAndFields = type.GetPropertiesAndFields().Where(p => p.CanSerialize).ToList();
// sometimes Octokit needs to send a null with the payload so the user
// can unset the value of a property.
// This method uses the same checks as PocoJsonSerializerStrategy
// to identify the right fields and properties to serialize
// but it then filters on the presence of SerializeNullAttribute.
foreach (var propertyOrField in type.GetPropertiesAndFields())
foreach (var property in propertiesAndFields.Where(p => p.SerializeNull))
{
if (!propertyOrField.CanRead)
continue;
if (propertyOrField.Base64Encoded)
{
_membersWhichShouldBeBase64Encoded.Add(fullName + MapClrMemberToJsonFieldName(propertyOrField.MemberInfo));
}
if (!propertyOrField.SerializeNull)
continue;
_membersWhichShouldPublishNull.Add(fullName + MapClrMemberToJsonFieldName(propertyOrField.MemberInfo));
var key = type.FullName + "-" + property.JsonFieldName;
_membersWhichShouldPublishNull.Add(key);
}
return base.GetterValueFactory(type);
return propertiesAndFields
.ToDictionary(
p => p.JsonFieldName,
p => p.GetDelegate);
}
// This is overridden so that null values are omitted from serialized objects.
@@ -77,15 +67,6 @@ namespace Octokit.Internal
if (!_membersWhichShouldPublishNull.Contains(key))
continue;
}
else
{
var key = type.FullName + "-" + getter.Key;
if (_membersWhichShouldBeBase64Encoded.Contains(key))
{
var stringValue = value as string ?? "";
value = stringValue.ToBase64String();
}
}
jsonObject.Add(getter.Key, value);
}
}