diff --git a/Bynder/Sdk/Api/Converters/ITypeToDictionaryConverter.cs b/Bynder/Sdk/Api/Converters/ITypeToDictionaryConverter.cs
new file mode 100644
index 0000000..6043497
--- /dev/null
+++ b/Bynder/Sdk/Api/Converters/ITypeToDictionaryConverter.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Bynder. All rights reserved.
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+
+namespace Bynder.Sdk.Api.Converters
+{
+ ///
+ /// Interface for type converters used to decode specific
+ /// parameters to strings
+ ///
+ public interface ITypeToDictionaryConverter
+ {
+ ///
+ /// Checks if the converter can convert a specific type
+ ///
+ /// Type to convert from
+ /// true if it can convert the type
+ bool CanConvert(Type typeToConvert);
+
+ ///
+ /// Converts the value to string
+ ///
+ /// value to be converted
+ /// converted string value
+ IDictionary Convert(object value);
+ }
+}
diff --git a/Bynder/Sdk/Api/Converters/MetapropertyOptionsConverter.cs b/Bynder/Sdk/Api/Converters/MetapropertyOptionsConverter.cs
new file mode 100644
index 0000000..fd603f9
--- /dev/null
+++ b/Bynder/Sdk/Api/Converters/MetapropertyOptionsConverter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Bynder.Sdk.Api.Converters
+{
+ public class MetapropertyOptionsConverter : ITypeToDictionaryConverter
+ {
+
+ public bool CanConvert(Type typeToConvert)
+ {
+ return typeof(IDictionary>).IsAssignableFrom(typeToConvert);
+ }
+
+ public IDictionary Convert(object value)
+ {
+ return ((IDictionary>)value).ToDictionary(
+ item => item.Key,
+ item => string.Join(",", item.Value)
+ );
+ }
+
+ }
+}
diff --git a/Bynder/Sdk/Bynder.Sdk.csproj b/Bynder/Sdk/Bynder.Sdk.csproj
index 5b3a8f2..600a317 100644
--- a/Bynder/Sdk/Bynder.Sdk.csproj
+++ b/Bynder/Sdk/Bynder.Sdk.csproj
@@ -1,13 +1,13 @@
netstandard2.1;net48
- 2.2.9.0
- 2.2.9.0
+ 2.2.10.0
+ 2.2.10.0
Bynder
Bynder.Sdk
Copyright © Bynder
true
- 2.2.9
+ 2.2.10
BynderDevops
The main goal of this SDK is to speed up the integration of Bynder customers who use C# making it easier to connect to the Bynder API (http://docs.bynder.apiary.io/) and executing requests on it.
BynderLogo.png
@@ -17,7 +17,7 @@
true
BynderDevops
https://github.com/Bynder/bynder-c-sharp-sdk
- The UploadFile call now returns data about the created asset.
+ Added "transformBaseUrl" field to Media model. Added functionality to create and delete asset usage records. Added functionality to pass metaproperty options during save & modify media.
The main goal of this SDK is to speed up the integration of Bynder customers who use C# making it easier to connect to the Bynder API (http://docs.bynder.apiary.io/) and executing requests on it.
Bynder API C# SDK
Bynder.Sdk
@@ -37,7 +37,7 @@
-
-
+
+
diff --git a/Bynder/Sdk/Query/Asset/ModifyMediaQuery.cs b/Bynder/Sdk/Query/Asset/ModifyMediaQuery.cs
index 8c753a6..fe571b7 100644
--- a/Bynder/Sdk/Query/Asset/ModifyMediaQuery.cs
+++ b/Bynder/Sdk/Query/Asset/ModifyMediaQuery.cs
@@ -1,5 +1,5 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
+using Bynder.Sdk.Api.Converters;
using Bynder.Sdk.Query.Decoder;
namespace Bynder.Sdk.Query.Asset
@@ -52,6 +52,22 @@ public ModifyMediaQuery(string mediaId)
///
[ApiField("isPublic")]
public bool IsPublic { get; set; }
+
+ ///
+ /// Metaproperty options to set on the asset.
+ ///
+ [ApiField("metaproperty", Converter = typeof(MetapropertyOptionsConverter))]
+ public IDictionary> MetapropertyOptions { get; set; }
+
+ ///
+ /// Add a set of options to a metaproperty
+ ///
+ /// metaproperty ID
+ /// set of options
+ public void AddMetapropertyOptions(string metapropertyId, IList optionIds)
+ {
+ MetapropertyOptions.Add(metapropertyId, optionIds);
+ }
}
}
diff --git a/Bynder/Sdk/Query/Decoder/QueryDecoder.cs b/Bynder/Sdk/Query/Decoder/QueryDecoder.cs
index e970363..345219b 100644
--- a/Bynder/Sdk/Query/Decoder/QueryDecoder.cs
+++ b/Bynder/Sdk/Query/Decoder/QueryDecoder.cs
@@ -41,20 +41,33 @@ public IDictionary GetParameters(object query)
/// property type information
/// query object
/// collection to add the converted values
- private void ConvertProperty(PropertyInfo propertyInfo, object query, IDictionary collection)
+ private void ConvertProperty(PropertyInfo propertyInfo, object query, IDictionary parameters)
{
- var attributes = propertyInfo.GetCustomAttributes(true);
- foreach (var attribute in attributes)
+ foreach (var attribute in propertyInfo.GetCustomAttributes(true))
{
- if (attribute is ApiField nameAttr)
+ if (attribute is ApiField apiField)
{
object value = propertyInfo.GetValue(query);
- if (value != null)
+ if (value == null)
{
- var convertedValue = ConvertPropertyValue(nameAttr, propertyInfo.PropertyType, value);
- if (!string.IsNullOrEmpty(convertedValue))
+ return;
+ }
+
+ if (apiField.Converter == null)
+ {
+ AddParam(parameters, apiField.ApiName, value.ToString());
+ }
+ else if (Activator.CreateInstance(apiField.Converter) is ITypeToStringConverter stringConverter
+ && stringConverter.CanConvert(propertyInfo.PropertyType))
+ {
+ AddParam(parameters, apiField.ApiName, stringConverter.Convert(value));
+ }
+ else if (Activator.CreateInstance(apiField.Converter) is ITypeToDictionaryConverter dictConverter
+ && dictConverter.CanConvert(propertyInfo.PropertyType))
+ {
+ foreach (var item in dictConverter.Convert(value))
{
- collection.Add(nameAttr.ApiName, convertedValue);
+ AddParam(parameters, $"{apiField.ApiName}.{item.Key}", item.Value);
}
}
@@ -64,21 +77,13 @@ private void ConvertProperty(PropertyInfo propertyInfo, object query, IDictionar
}
}
- ///
- /// Function called to convert property values to string. If no converter is
- /// specified, then .ToString is called.
- ///
- /// API field attribute
- /// property type information
- /// current value
- /// converted value
- private string ConvertPropertyValue(ApiField apiField, Type propertyType, object value)
+ private void AddParam(IDictionary parameters, string key, string value)
{
- return apiField.Converter != null
- && Activator.CreateInstance(apiField.Converter) is ITypeToStringConverter converter
- && converter.CanConvert(propertyType)
- ? converter.Convert(value)
- : value.ToString();
+ if (!string.IsNullOrEmpty(value))
+ {
+ parameters.Add(key, value);
+ }
}
+
}
}
diff --git a/Bynder/Sdk/Query/Upload/SaveMediaQuery.cs b/Bynder/Sdk/Query/Upload/SaveMediaQuery.cs
index 0f48b5d..0d8e01b 100644
--- a/Bynder/Sdk/Query/Upload/SaveMediaQuery.cs
+++ b/Bynder/Sdk/Query/Upload/SaveMediaQuery.cs
@@ -42,5 +42,22 @@ internal class SaveMediaQuery
///
[ApiField("tags", Converter = typeof(ListConverter))]
public IList Tags { get; set; }
+
+ ///
+ /// Metaproperty options to set on the asset.
+ ///
+ [ApiField("metaproperty", Converter = typeof(MetapropertyOptionsConverter))]
+ public IDictionary> MetapropertyOptions { get; set; } = new Dictionary>();
+
+ ///
+ /// Add a set of options to a metaproperty
+ ///
+ /// metaproperty ID
+ /// set of options
+ public void AddMetapropertyOptions(string metapropertyId, IList optionIds)
+ {
+ MetapropertyOptions.Add(metapropertyId, optionIds);
+ }
+
}
}
diff --git a/Bynder/Test/Api/Converters/MetapropertyOptionsConverterTest.cs b/Bynder/Test/Api/Converters/MetapropertyOptionsConverterTest.cs
new file mode 100644
index 0000000..1902b1d
--- /dev/null
+++ b/Bynder/Test/Api/Converters/MetapropertyOptionsConverterTest.cs
@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using Bynder.Sdk.Api.Converters;
+using Xunit;
+
+namespace Bynder.Test.Api.Converters
+{
+ public class MetapropertyOptionsConverterTest
+ {
+ [Fact]
+ public void CanConvertOnlyWhenTypeIsDateTimeOffset()
+ {
+ var converter = new MetapropertyOptionsConverter();
+ Assert.False(converter.CanConvert(typeof(int)));
+ Assert.False(converter.CanConvert(typeof(string)));
+ Assert.False(converter.CanConvert(typeof(bool)));
+ Assert.True(converter.CanConvert(typeof(IDictionary>)));
+ }
+
+ [Fact]
+ public void ConvertReturnsStringWithDate()
+ {
+ const string metaprop1 = "metaprop1";
+ const string metaprop1option1 = "metaprop1option1";
+ const string metaprop1option2 = "metaprop1option2";
+ const string metaprop1option3 = "metaprop1option3";
+
+ const string metaprop2 = "metaprop2";
+ const string metaprop2option1 = "metaprop2option1";
+ const string metaprop2option2 = "metaprop2option2";
+ const string metaprop2option3 = "metaprop2option3";
+
+ const string metaprop3 = "metaprop3";
+ const string metaprop3option1 = "metaprop3option1";
+ const string metaprop3option2 = "metaprop3option2";
+ const string metaprop3option3 = "metaprop3option3";
+
+ var converter = new MetapropertyOptionsConverter();
+ var converted = converter.Convert(new Dictionary>
+ {
+ { metaprop1, new List { metaprop1option1, metaprop1option2, metaprop1option3 } },
+ { metaprop2, new List { metaprop2option1, metaprop2option2, metaprop2option3 } },
+ { metaprop3, new List { metaprop3option1, metaprop3option2, metaprop3option3 } }
+ });
+ var expected = new Dictionary
+ {
+ { metaprop1, $"{metaprop1option1},{metaprop1option2},{metaprop1option3}" },
+ { metaprop2, $"{metaprop2option1},{metaprop2option2},{metaprop2option3}" },
+ { metaprop3, $"{metaprop3option1},{metaprop3option2},{metaprop3option3}" }
+ };
+ Assert.Equal(expected, converted);
+ }
+ }
+}
diff --git a/Bynder/Test/Query/Decoder/QueryDecoderTest.cs b/Bynder/Test/Query/Decoder/QueryDecoderTest.cs
index fa9e5b0..2749eb6 100644
--- a/Bynder/Test/Query/Decoder/QueryDecoderTest.cs
+++ b/Bynder/Test/Query/Decoder/QueryDecoderTest.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
using System;
+using System.Collections.Generic;
using Bynder.Sdk.Api.Converters;
using Bynder.Sdk.Query.Decoder;
using Xunit;
@@ -10,6 +11,23 @@ namespace Bynder.Test.Api
{
public class QueryDecoderTest
{
+ private const string _stringItem1ApiField = "string1ApiField";
+ private const string _stringItem2ApiField = "string2ApiField";
+ private const string _dictItemApiField = "dictApiField";
+
+ private const string _item = "item";
+ private const string _stringItem1 = "string1";
+ private const string _stringItem2 = "string2";
+
+ private const string _converted = "converted";
+
+ private const string _dictKey1 = "dictKey1";
+ private const string _dictKey2 = "dictKey2";
+ private const string _dictKey3 = "dictKey3";
+ private const string _dictValue1 = "dictValue1";
+ private const string _dictValue2 = "dictValue2";
+ private const string _dictValue3 = "dictValue3";
+
///
/// Tests that returns
/// only the parameters properties that have the attribute.
@@ -20,16 +38,16 @@ public void WhenQueryPassedThenOnlyAPIFieldAttributesAreReturned()
var queryDecoder = new QueryDecoder();
var parameters = queryDecoder.GetParameters(new StubQuery
{
- Item1 = "1",
- Item2 = "2",
- Item3 = "3"
+ Item = _item,
+ StringItem1 = _stringItem1,
+ StringItem2 = _stringItem2
});
- // Property Item3 should not appear as it does not have APIField attribute
+ // Unannotated property should not appear as it does not have APIField attribute
Assert.Equal(2, parameters.Count);
- Assert.Equal("1", parameters["Item1"]);
- Assert.Equal("2", parameters["Item2"]);
+ Assert.Equal(_stringItem1, parameters[_stringItem1ApiField]);
+ Assert.Equal(_stringItem2, parameters[_stringItem2ApiField]);
}
///
@@ -42,10 +60,14 @@ public void WhenQueryAttributeHasConverterThenParameterValueIsConverted()
var queryDecoder = new QueryDecoder();
var parameters = queryDecoder.GetParameters(new StubConverterQuery
{
- Item1 = "1"
+ StringItem = _stringItem1,
+ DictItem = 42
});
- Assert.Equal("Converted", parameters["Item1"]);
+ Assert.Equal(_converted, parameters[_stringItem1ApiField]);
+ Assert.Equal(_dictValue1, parameters[$"{_dictItemApiField}.{_dictKey1}"]);
+ Assert.Equal(_dictValue2, parameters[$"{_dictItemApiField}.{_dictKey2}"]);
+ Assert.Equal(_dictValue3, parameters[$"{_dictItemApiField}.{_dictKey3}"]);
}
///
@@ -56,25 +78,25 @@ private class StubQuery
///
/// Stub property.
///
- [ApiField("Item1")]
- public string Item1 { get; set; }
+ [ApiField(_stringItem1ApiField)]
+ public string StringItem1 { get; set; }
///
/// Stub property.
///
- [ApiField("Item2")]
- public string Item2 { get; set; }
+ [ApiField(_stringItem2ApiField)]
+ public string StringItem2 { get; set; }
///
/// Stub property.
///
- public string Item3 { get; set; }
+ public string Item { get; set; }
}
///
/// Stub converter only used for testing purposes.
///
- private class StubDecoder : ITypeToStringConverter
+ private class StubStringConverter : ITypeToStringConverter
{
///
/// Check .
@@ -93,7 +115,38 @@ public bool CanConvert(Type typeToConvert)
/// Check
public string Convert(object value)
{
- return "Converted";
+ return _converted;
+ }
+ }
+
+ ///
+ /// Stub converter only used for testing purposes.
+ ///
+ private class StubDictionaryConverter : ITypeToDictionaryConverter
+ {
+ ///
+ /// Check .
+ ///
+ /// Check
+ /// Check
+ public bool CanConvert(Type typeToConvert)
+ {
+ return true;
+ }
+
+ ///
+ /// Check .
+ ///
+ /// Check
+ /// Check
+ public IDictionary Convert(object value)
+ {
+ return new Dictionary
+ {
+ { _dictKey1, _dictValue1 },
+ { _dictKey2, _dictValue2 },
+ { _dictKey3, _dictValue3 }
+ };
}
}
@@ -105,8 +158,14 @@ private class StubConverterQuery
///
/// Stub property.
///
- [ApiField("Item1", Converter = typeof(StubDecoder))]
- public string Item1 { get; set; }
+ [ApiField(_stringItem1ApiField, Converter = typeof(StubStringConverter))]
+ public string StringItem { get; set; }
+
+ ///
+ /// Stub property.
+ ///
+ [ApiField(_dictItemApiField, Converter = typeof(StubDictionaryConverter))]
+ public int DictItem { get; set; }
}
}
}