Last active
July 19, 2017 09:58
-
-
Save vSzemkel/7f74819f02fede9851dab53262d316fc to your computer and use it in GitHub Desktop.
QueryStringObjectSerializer enables caching sophisticated results of GET search requests in favor of POST noncachable ones
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ----------------------------------------------------------------------- | |
// <copyright file="QueryStringObjectSerializer.cs" company="Agora SA"> | |
// Copyright (c) TDE - Development IT , lipiec 2017 | |
// <author>Marcin Buchwald</author> | |
// </copyright> | |
// ----------------------------------------------------------------------- | |
namespace NewsMavens.Models.Helpers | |
{ | |
using System; | |
using System.Reflection; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Newtonsoft.Json; | |
public static class QueryStringObjectSerializer | |
{ | |
/// <summary> | |
/// Serializer | |
/// </summary> | |
/// <typeparam name="T">Flat structure of primitive types or List of bytes</typeparam> | |
/// <param name="nameValueCollection">output </param> | |
/// <param name="parm">Search structure</param> | |
public static void Serialize<T>(Dictionary<string,string> nameValueCollection, T parm) where T : class | |
{ | |
var type = typeof(T); | |
var fields = type.GetRuntimeFields(); | |
var patern = Activator.CreateInstance(type); | |
foreach (var field in fields) { | |
var value = field.GetValue(parm); | |
if (value == null || value.ToString() == field.GetValue(patern)?.ToString()) | |
continue; | |
var key = field.Name; | |
var valType = value.GetType(); | |
if (valType.GetTypeInfo().IsEnum) | |
nameValueCollection.Add(key, ((byte) value).ToString()); | |
else if (valType == typeof(List<byte>)) | |
nameValueCollection.Add(key, JsonConvert.SerializeObject(value)); | |
else | |
nameValueCollection.Add(key, value.ToString()); | |
} | |
} | |
/// <summary> | |
/// Deserialize query string to an instance of T | |
/// </summary> | |
/// <typeparam name="T">Flat structure of primitive types or List of bytes</typeparam> | |
/// <param name="queryString">query string</param> | |
/// <returns>an instance of T</returns> | |
public static T Deserialize<T>(string queryString) where T : class, new() | |
{ | |
var result = new T(); | |
var parms = queryString.Split('&'); | |
var fields = typeof(T).GetRuntimeFields(); | |
foreach (var query in parms) | |
foreach (var field in fields) | |
if (query.StartsWith(field.Name)) { | |
var valueType = field.FieldType; | |
var stringValue = GetQueryValue(query); | |
if (valueType == typeof(List<byte>)) | |
field.SetValue(result, JsonConvert.DeserializeObject<List<byte>>(stringValue)); | |
else if (valueType.GetTypeInfo().IsEnum) | |
field.SetValue(result, byte.Parse(stringValue)); | |
else { | |
var baseType = Nullable.GetUnderlyingType(valueType); | |
var value = Convert.ChangeType(stringValue, baseType ?? valueType); | |
field.SetValue(result, value); | |
} | |
} | |
return result; | |
} | |
/// <summary> | |
/// Appends query string to base url | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="url">Valid URL prefix ending with '?' or '&'</param> | |
/// <param name="queryStringParams">Structure to serialize in query string</param> | |
/// <returns></returns> | |
public static string BuildCall<T>(string url, T queryStringParams) where T : class | |
{ | |
var queryStringBuilder = new Dictionary<string, string>(); | |
QueryStringObjectSerializer.Serialize(queryStringBuilder, queryStringParams); | |
var qs = new StringBuilder(url); | |
if (url.Contains('?')) { | |
if (!url.EndsWith("&")) | |
qs.Append('&'); | |
} else | |
qs.Append('?'); | |
foreach (var keyVal in queryStringBuilder) | |
qs.Append($"{keyVal.Key}={keyVal.Value}&"); | |
qs.Length--; | |
return qs.ToString(); | |
} | |
/// <summary> | |
/// Generates string hash of queryStringParams | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="queryStringParams">Structure to serialize in query string</param> | |
/// <returns></returns> | |
public static string GenerateQueryStringHash<T>(T queryStringParams) where T : class | |
{ | |
var queryStringBuilder = new Dictionary<string, string>(); | |
QueryStringObjectSerializer.Serialize(queryStringBuilder, queryStringParams); | |
var qs = new StringBuilder(100); | |
foreach (var keyVal in queryStringBuilder) | |
qs.Append($"{keyVal.Key}{keyVal.Value}"); | |
return qs.ToString(); | |
} | |
/// <summary> | |
/// Extracts a value from "key=value" string | |
/// </summary> | |
/// <param name="query">query string</param> | |
/// <returns>value part of the input string</returns> | |
private static string GetQueryValue(string query) | |
{ | |
string value = string.Empty; | |
var pos = query.IndexOf('='); | |
if (pos > 0) value = query.Substring(pos + 1); | |
return value; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment