Skip to content

Fixed dictionary item value serialization issue - Part 2 #445

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

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,7 @@ public void Serialize_ShouldNotCamelCaseBindVars_WhenSerializingPostCursorBody()

byte[] jsonBytes = serialization.Serialize(body, new ApiClientSerializationOptions(
useCamelCasePropertyNames: true,
ignoreNullValues: true,
camelCasePropertyNamesOfObjectValuesInDictionaries: false));
ignoreNullValues: true));

string jsonString = Encoding.UTF8.GetString(jsonBytes);

Expand All @@ -173,28 +172,28 @@ public void Serialize_ShouldNotCamelCaseBindVars_WhenSerializingPostCursorBody()
}

[Fact]
public void Serialize_ShouldCamelCaseBindVars_WhenSerializingPostCursorBody()
public void Serialize_ShouldCamelCaseBindVars_WhenSerializingPostCursorBodyWithDictionaryOption()
{
var body = new PostCursorBody
{
BindVars = new Dictionary<string, object>
{
["DontCamelCaseKey"] = new { DontCamelCaseMe = true }
["CamelCaseKey"] = new { CamelCaseMe = true }
}
};
var serialization = new JsonNetApiClientSerialization();

byte[] jsonBytes = serialization.Serialize(body, new ApiClientSerializationOptions(
useCamelCasePropertyNames: true,
ignoreNullValues: true,
camelCasePropertyNamesOfObjectValuesInDictionaries: true));
ignoreNullValues: true,
applySerializationOptionsToDictionaryValues: true));

string jsonString = Encoding.UTF8.GetString(jsonBytes);

Assert.Contains("DontCamelCaseKey", jsonString);
Assert.DoesNotContain("dontCamelCaseKey", jsonString);
Assert.Contains("dontCamelCaseMe", jsonString);
Assert.DoesNotContain("DontCamelCaseMe", jsonString);
Assert.Contains("CamelCaseKey", jsonString);
Assert.DoesNotContain("camelCaseKey", jsonString);
Assert.Contains("camelCaseMe", jsonString);
Assert.DoesNotContain("CamelCaseMe", jsonString);
}

[Fact]
Expand All @@ -212,8 +211,7 @@ public void Serialize_ShouldNotCamelCaseParams_WhenSerializingPostTransactionBod

byte[] jsonBytes = serialization.Serialize(body, new ApiClientSerializationOptions(
useCamelCasePropertyNames: true,
ignoreNullValues: true,
camelCasePropertyNamesOfObjectValuesInDictionaries: false));
ignoreNullValues: true));

string jsonString = Encoding.UTF8.GetString(jsonBytes);

Expand All @@ -225,13 +223,13 @@ public void Serialize_ShouldNotCamelCaseParams_WhenSerializingPostTransactionBod


[Fact]
public void Serialize_ShouldCamelCaseParams_WhenSerializingPostTransactionBody()
public void Serialize_ShouldCamelCaseParams_WhenSerializingPostTransactionBodyWithDictionaryOption()
{
var body = new PostTransactionBody
{
Params = new Dictionary<string, object>
{
["DontCamelCaseKey"] = new { DontCamelCaseMe = true }
["CamelCaseKey"] = new { CamelCaseMe = true }
}
};

Expand All @@ -240,14 +238,14 @@ public void Serialize_ShouldCamelCaseParams_WhenSerializingPostTransactionBody()
byte[] jsonBytes = serialization.Serialize(body, new ApiClientSerializationOptions(
useCamelCasePropertyNames: true,
ignoreNullValues: true,
camelCasePropertyNamesOfObjectValuesInDictionaries: true));
applySerializationOptionsToDictionaryValues: true));

string jsonString = Encoding.UTF8.GetString(jsonBytes);

Assert.Contains("DontCamelCaseKey", jsonString);
Assert.DoesNotContain("dontCamelCaseKey", jsonString);
Assert.Contains("dontCamelCaseMe", jsonString);
Assert.DoesNotContain("DontCamelCaseMe", jsonString);
Assert.Contains("CamelCaseKey", jsonString);
Assert.DoesNotContain("camelCaseKey", jsonString);
Assert.Contains("camelCaseMe", jsonString);
Assert.DoesNotContain("CamelCaseMe", jsonString);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public abstract class ApiClientSerialization : IApiClientSerialization
ignoreNullValues: true,
useStringEnumConversion: false,
ignoreMissingMember: true,
camelCasePropertyNamesOfObjectValuesInDictionaries: false);
applySerializationOptionsToDictionaryValues: false);

/// <summary>
/// Deserializes the data structure contained by the specified stream
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ public class ApiClientSerializationOptions
public bool UseStringEnumConversion { get; set; }

/// <summary>
/// True to camel case the names of properties of object values
/// True to apply serialization options to object values
/// in dictionaries (i.e. CamelCaseMe => "camelCaseMe").
/// False to leave the names of properties of object values
/// in dictionaries as they are (i.e. DontCamelCaseMe => "DontCamelCaseMe")
/// False to not apply serialization options to object values
/// in dictionaries (i.e. leave the names of properties of object values
/// in dictionaries as they are: DontCamelCaseMe => "DontCamelCaseMe")
/// </summary>
public bool CamelCasePropertyNamesOfObjectValuesInDictionaries { get; set; }
public bool ApplySerializationOptionsToDictionaryValues { get; set; }

/// <summary>
/// Create serialization options.
Expand All @@ -42,19 +43,19 @@ public class ApiClientSerializationOptions
/// <param name="ignoreNullValues">Whether null values should be ignored - i.e. not defined at all in the serialized string.</param>
/// <param name="useStringEnumConversion">Whether to serialize enum values to a string value instead of an integer.</param>
/// <param name="ignoreMissingMember">Whether missing members should be ignored.</param>
/// <param name="camelCasePropertyNamesOfObjectValuesInDictionaries">Whether to camel case the names of properties of object values in dictionaries.</param>
/// <param name="applySerializationOptionsToDictionaryValues">Whether to apply serialization options to object values in dictionaries.</param>
public ApiClientSerializationOptions(
bool useCamelCasePropertyNames,
bool ignoreNullValues,
bool useStringEnumConversion = false,
bool ignoreMissingMember = true,
bool camelCasePropertyNamesOfObjectValuesInDictionaries = false)
bool applySerializationOptionsToDictionaryValues = false)
{
UseCamelCasePropertyNames = useCamelCasePropertyNames;
IgnoreNullValues = ignoreNullValues;
UseStringEnumConversion = useStringEnumConversion;
IgnoreMissingMember = ignoreMissingMember;
CamelCasePropertyNamesOfObjectValuesInDictionaries = camelCasePropertyNamesOfObjectValuesInDictionaries;
ApplySerializationOptionsToDictionaryValues = applySerializationOptionsToDictionaryValues;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
{
// Use a local serializer for writing instead of the passed-in serializer
JsonSerializer mySerializer;
if (_serializationOptions != null && _serializationOptions.CamelCasePropertyNamesOfObjectValuesInDictionaries)
if (_serializationOptions != null && _serializationOptions.ApplySerializationOptionsToDictionaryValues)
{
mySerializer = new JsonSerializer
{
Expand Down
23 changes: 19 additions & 4 deletions arangodb-net-standard/ViewApi/IViewsApiClient.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using ArangoDBNetStandard.Serialization;
using ArangoDBNetStandard.ViewApi.Models;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -24,10 +25,14 @@ Task<GetAllViewsResponse> GetAllViewsAsync(
/// POST /_api/view
/// </summary>
/// <param name="body">The body of the request containing required properties.</param>
/// <param name="ignoreNullValuesOnSerialization">
/// Indicates whether to ignore null values during serialization.
/// This parameter can be used together with <see cref="LinkProperties.IncludeAllFields"/>
/// set to false to control if fields with null values are included.
/// </param>
/// <param name="token">A CancellationToken to observe while waiting for the task to complete or to cancel the task.</param>
/// <returns></returns>
Task<ViewResponse> PostCreateViewAsync(ViewDetails body,
CancellationToken token = default);
Task<ViewResponse> PostCreateViewAsync(ViewDetails body, bool ignoreNullValuesOnSerialization = true, CancellationToken token = default);

/// <summary>
/// Delete / drop a view
Expand Down Expand Up @@ -65,9 +70,14 @@ Task<GetViewPropertiesResponse> GetViewPropertiesAsync(string viewNameOrId,
/// </summary>
/// <param name="viewNameOrId">The name or identifier of the view.</param>
/// <param name="body">The body of the request containing required properties.</param>
/// <param name="ignoreNullValuesOnSerialization">
/// Indicates whether to ignore null values during serialization.
/// This parameter can be used together with <see cref="LinkProperties.IncludeAllFields"/>
/// set to false to control if fields with null values are included.
/// </param>
/// <param name="token">A CancellationToken to observe while waiting for the task to complete or to cancel the task.</param>
/// <returns></returns>
Task<ViewResponse> PatchViewPropertiesAsync(string viewNameOrId, ViewDetails body,
Task<ViewResponse> PatchViewPropertiesAsync(string viewNameOrId, ViewDetails body, bool ignoreNullValuesOnSerialization = true,
CancellationToken token = default);

/// <summary>
Expand All @@ -76,9 +86,14 @@ Task<ViewResponse> PatchViewPropertiesAsync(string viewNameOrId, ViewDetails bod
/// </summary>
/// <param name="viewName">The name of the view.</param>
/// <param name="body">The body of the request containing required properties.</param>
/// <param name="ignoreNullValuesOnSerialization">
/// Indicates whether to ignore null values during serialization.
/// This parameter can be used together with <see cref="LinkProperties.IncludeAllFields"/>
/// set to false to control if fields with null values are included.
/// </param>
/// <param name="token">A CancellationToken to observe while waiting for the task to complete or to cancel the task.</param>
/// <returns></returns>
Task<ViewResponse> PutViewPropertiesAsync(string viewName, ViewDetails body,
Task<ViewResponse> PutViewPropertiesAsync(string viewName, ViewDetails body, bool ignoreNullValuesOnSerialization = true,
CancellationToken token = default);

/// <summary>
Expand Down
46 changes: 36 additions & 10 deletions arangodb-net-standard/ViewApi/ViewsApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,22 @@ public virtual async Task<GetAllViewsResponse> GetAllViewsAsync(
/// POST /_api/view
/// </summary>
/// <param name="body">The body of the request containing required properties.</param>
/// <param name="ignoreNullValuesOnSerialization">
/// Indicates whether to ignore null values during serialization.
/// This parameter can be used together with <see cref="LinkProperties.IncludeAllFields"/>
/// set to false to control if fields with null values are included.
/// </param>
/// <param name="token">A CancellationToken to observe while waiting for the task to complete or to cancel the task.</param>
/// <returns></returns>
public virtual async Task<ViewResponse> PostCreateViewAsync(ViewDetails body,
CancellationToken token = default)
public virtual async Task<ViewResponse> PostCreateViewAsync(ViewDetails body, bool ignoreNullValuesOnSerialization=true, CancellationToken token = default)
{
string uri = _apiPath;
var content = GetContent(body, new ApiClientSerializationOptions(true, true));
using (var response = await _transport.PostAsync(uri, content, token: token).ConfigureAwait(false))
var content = GetContent(body,
new ApiClientSerializationOptions(
useCamelCasePropertyNames: true,
ignoreNullValues: ignoreNullValuesOnSerialization,
applySerializationOptionsToDictionaryValues: true));
using (var response = await _transport.PostAsync(uri, content).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
Expand Down Expand Up @@ -163,13 +171,22 @@ public virtual async Task<GetViewPropertiesResponse> GetViewPropertiesAsync(stri
/// </summary>
/// <param name="viewNameOrId">The name or identifier of the view.</param>
/// <param name="body">The body of the request containing required properties.</param>
/// <param name="ignoreNullValuesOnSerialization">
/// Indicates whether to ignore null values during serialization.
/// This parameter can be used together with <see cref="LinkProperties.IncludeAllFields"/>
/// set to false to control if fields with null values are included.
/// </param>
/// <param name="token">A CancellationToken to observe while waiting for the task to complete or to cancel the task.</param>
/// <returns></returns>
public virtual async Task<ViewResponse> PatchViewPropertiesAsync(string viewNameOrId, ViewDetails body,
CancellationToken token = default)
public virtual async Task<ViewResponse> PatchViewPropertiesAsync(string viewNameOrId, ViewDetails body,
bool ignoreNullValuesOnSerialization = true, CancellationToken token = default)
{
string uri = $"{_apiPath}/{viewNameOrId}/properties";
var content = GetContent(body, new ApiClientSerializationOptions(true, true));
var content = GetContent(body,
new ApiClientSerializationOptions(
useCamelCasePropertyNames: true,
ignoreNullValues: ignoreNullValuesOnSerialization,
applySerializationOptionsToDictionaryValues: true));
using (var response = await _transport.PatchAsync(uri, content, token: token).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
Expand All @@ -187,13 +204,22 @@ public virtual async Task<ViewResponse> PatchViewPropertiesAsync(string viewName
/// </summary>
/// <param name="viewName">The name of the view.</param>
/// <param name="body">The body of the request containing required properties.</param>
/// <param name="ignoreNullValuesOnSerialization">
/// Indicates whether to ignore null values during serialization.
/// This parameter can be used together with <see cref="LinkProperties.IncludeAllFields"/>
/// set to false to control if fields with null values are included.
/// </param>
/// <param name="token">A CancellationToken to observe while waiting for the task to complete or to cancel the task.</param>
/// <returns></returns>
public virtual async Task<ViewResponse> PutViewPropertiesAsync(string viewName, ViewDetails body,
CancellationToken token = default)
public virtual async Task<ViewResponse> PutViewPropertiesAsync(string viewName, ViewDetails body,
bool ignoreNullValuesOnSerialization = true, CancellationToken token = default)
{
string uri = $"{_apiPath}/{viewName}/properties";
var content = GetContent(body, new ApiClientSerializationOptions(true, true));
var content = GetContent(body,
new ApiClientSerializationOptions(
useCamelCasePropertyNames: true,
ignoreNullValues: ignoreNullValuesOnSerialization,
applySerializationOptionsToDictionaryValues: true));
using (var response = await _transport.PutAsync(uri, content, token: token).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
Expand Down