Skip to content

Instantly share code, notes, and snippets.

@MikaelElkiaer
Last active August 7, 2019 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MikaelElkiaer/52851beee9cefaa31339ebfcdfe1730c to your computer and use it in GitHub Desktop.
Save MikaelElkiaer/52851beee9cefaa31339ebfcdfe1730c to your computer and use it in GitHub Desktop.
Custom UrlEncodedSerializer that utilizes DataContract and DataMember attributes
public class DataContractUrlEncodedSerializer : ISerializer
{
/// <summary>
/// Serializes the specified object utilizing DataContract and DataMembers if present.
/// </summary>
/// <param name="obj">The object.</param>
public string Serialize(object obj)
{
if (obj == null)
return null;
bool useDataMembers = TryGetDataMembers(obj, out IDictionary<string, string> dataMembers);
var qp = new QueryParamCollection();
foreach (var kv in obj.ToKeyValuePairs())
{
string key = useDataMembers && dataMembers.TryGetValue(kv.Key, out string dataKey) ? dataKey : kv.Key;
qp.Merge(key, kv.Value, false, NullValueHandling.Ignore);
}
return qp.ToString(true);
}
private bool TryGetDataMembers(object obj, out IDictionary<string, string> dataMembers)
{
dataMembers = null;
if (HasDataContract(obj))
{
dataMembers = obj.GetType().GetProperties()
.Where(HasDataMember)
.Select(ToDataMember)
.ToDictionary(p => p.PropertyName, p => p.DataMemberName);
return true;
}
return false;
}
private bool HasDataMember(PropertyInfo pi) =>
Attribute.IsDefined(pi, typeof(DataMemberAttribute));
private bool HasDataContract(object obj) =>
obj.GetType().GetCustomAttributes(typeof(DataContractAttribute), true).Any();
private static (string PropertyName, string DataMemberName) ToDataMember(PropertyInfo pi) =>
(pi.Name, ((DataMemberAttribute)Attribute.GetCustomAttribute(pi, typeof(DataMemberAttribute))).Name);
/// <summary>
/// Deserializes the specified s.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="s">The s.</param>
/// <exception cref="NotImplementedException">Deserializing to UrlEncoded not supported.</exception>
public T Deserialize<T>(string s)
{
throw new NotImplementedException("Deserializing to UrlEncoded is not supported.");
}
/// <summary>
/// Deserializes the specified stream.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream">The stream.</param>
/// <exception cref="NotImplementedException">Deserializing to UrlEncoded not supported.</exception>
public T Deserialize<T>(Stream stream)
{
throw new NotImplementedException("Deserializing to UrlEncoded is not supported.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment