From d0dcbe8fb6901c116fed1eeeee06023bda5d6ee3 Mon Sep 17 00:00:00 2001 From: "Matt G. Ellis" Date: Mon, 17 Nov 2014 22:52:01 -0800 Subject: [PATCH] Allow [Parameter] to control JSON Field Names. Previously, SimpleJsonSerializer.MapClrMemberNameToJsonFieldName special cased the name "Links" since while that was the name of the property in the object model, in JSON "_links" was used instead. It turns out that there was an additional problem, where GitReference wants to expose as Repository, but the name in JSON responses is "repo". Instead of simply adding another special case to MapClrMemberNameToJsonFieldName, we update the implementation of the serializer to allow [Parameter(Key = "some_name")] to denote what name we'd like to use for the field in the JSON object when we serialize. --- Octokit.Tests/SimpleJsonSerializerTests.cs | 3 ++- Octokit/Http/SimpleJsonSerializer.cs | 20 +++++++++++++------- Octokit/Models/Response/Feed.cs | 2 ++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Octokit.Tests/SimpleJsonSerializerTests.cs b/Octokit.Tests/SimpleJsonSerializerTests.cs index 6a7d3327..499d26c2 100644 --- a/Octokit.Tests/SimpleJsonSerializerTests.cs +++ b/Octokit.Tests/SimpleJsonSerializerTests.cs @@ -135,7 +135,7 @@ namespace Octokit.Tests } [Fact] - public void IgnoresUnderscore() + public void RespectsParameterKeyName() { const string json = "{\"_links\":\"blah\"}"; @@ -151,6 +151,7 @@ namespace Octokit.Tests public string FirstName { get; set; } public bool IsSomething { get; set; } public bool Private { get; set; } + [Parameter(Key = "_links")] public string Links { get; set; } } } diff --git a/Octokit/Http/SimpleJsonSerializer.cs b/Octokit/Http/SimpleJsonSerializer.cs index 91d54df9..3c879970 100644 --- a/Octokit/Http/SimpleJsonSerializer.cs +++ b/Octokit/Http/SimpleJsonSerializer.cs @@ -26,11 +26,17 @@ namespace Octokit.Internal readonly List _membersWhichShouldPublishNull = new List(); - protected override string MapClrMemberNameToJsonFieldName(string clrPropertyName) + protected override string MapClrMemberToJsonFieldName(MemberInfo member) { - var rubyCased = clrPropertyName.ToRubyCase(); - if (rubyCased == "links") return "_links"; // Special case for GitHub API - return rubyCased; + var memberName = member.Name; + var paramAttr = member.GetCustomAttribute(); + + if (paramAttr != null && !string.IsNullOrEmpty(paramAttr.Key)) + { + memberName = paramAttr.Key; + } + + return memberName.ToRubyCase(); } internal override IDictionary GetterValueFactory(Type type) @@ -53,7 +59,7 @@ namespace Octokit.Internal var attribute = propertyInfo.GetCustomAttribute(); if (attribute == null) continue; - _membersWhichShouldPublishNull.Add(fullName + MapClrMemberNameToJsonFieldName(propertyInfo.Name)); + _membersWhichShouldPublishNull.Add(fullName + MapClrMemberToJsonFieldName(propertyInfo)); } foreach (var fieldInfo in ReflectionUtils.GetFields(type)) { @@ -62,7 +68,7 @@ namespace Octokit.Internal var attribute = fieldInfo.GetCustomAttribute(); if (attribute == null) continue; - _membersWhichShouldPublishNull.Add(fullName + MapClrMemberNameToJsonFieldName(fieldInfo.Name)); + _membersWhichShouldPublishNull.Add(fullName + MapClrMemberToJsonFieldName(fieldInfo)); } return base.GetterValueFactory(type); @@ -89,7 +95,7 @@ namespace Octokit.Internal continue; } - jsonObject.Add(MapClrMemberNameToJsonFieldName(getter.Key), value); + jsonObject.Add(getter.Key, value); } } output = jsonObject; diff --git a/Octokit/Models/Response/Feed.cs b/Octokit/Models/Response/Feed.cs index 5dced3a5..8a517cc2 100644 --- a/Octokit/Models/Response/Feed.cs +++ b/Octokit/Models/Response/Feed.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Threading.Tasks; +using Octokit.Internal; namespace Octokit { @@ -45,6 +46,7 @@ namespace Octokit /// /// List of feed urls including feed url and feed type, e.g. application/atom+xml /// + [Parameter(Key = "_links")] public FeedLinks Links { get; set; } internal string DebuggerDisplay