101 votes

Comment sérialiser un objet au format de chaîne de requête ?

Comment sérialiser un objet au format de chaîne de requête ? Je n'arrive pas à trouver de réponse sur google. Merci.

Voici l'objet que je vais sérialiser à titre d'exemple.

 public class EditListItemActionModel
{
    public int? Id { get; set; }
    public int State { get; set; }
    public string Prefix { get; set; }
    public string Index { get; set; }
    public int? ParentID { get; set; }
}

26voto

yo hal Points 1949

En utilisant Json.Net ce serait beaucoup plus facile, en sérialisant puis en désérialisant en paires clé-valeur.

Voici un exemple de code :

 using Newtonsoft.Json;
using System.Web;

string ObjToQueryString(object obj)
{
     var step1 = JsonConvert.SerializeObject(obj);

     var step2 = JsonConvert.DeserializeObject<IDictionary<string, string>>(step1);

     var step3 = step2.Select(x => HttpUtility.UrlEncode(x.Key) + "=" + HttpUtility.UrlEncode(x.Value));

     return string.Join("&", step3);
}

13voto

Alvis Points 384

Sur la base des réponses populaires, je devais également mettre à jour le code pour prendre en charge les tableaux. Partage de la mise en œuvre :

 public string GetQueryString(object obj)
{
    var result = new List<string>();
    var props = obj.GetType().GetProperties().Where(p => p.GetValue(obj, null) != null);
    foreach (var p in props)
    {
        var value = p.GetValue(obj, null);
        var enumerable = value as ICollection;
        if (enumerable != null)
        {
            result.AddRange(from object v in enumerable select string.Format("{0}={1}", p.Name, HttpUtility.UrlEncode(v.ToString())));
        }
        else
        {
            result.Add(string.Format("{0}={1}", p.Name, HttpUtility.UrlEncode(value.ToString())));
        }
    }

    return string.Join("&", result.ToArray());
}

5voto

giorgi02 Points 114

Il sera également utile pour les objets imbriqués

 public static class HttpQueryStrings
{
    public static string ToQueryString<T>(this T @this) where T : class
    {
        StringBuilder query = @this.ToQueryStringBuilder();

        if (query.Length > 0)
            query[0] = '?';

        return query.ToString();
    }

    private static StringBuilder ToQueryStringBuilder<T>(this T obj, string prefix = "") where T : class
    {
        var gatherer = new StringBuilder();

        foreach (var p in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if (p.GetValue(obj, new object[0]) != null)
            {
                var value = p.GetValue(obj, new object[0]);

                if (p.PropertyType.IsArray && value.GetType() == typeof(DateTime[]))
                    foreach (var item in value as DateTime[])
                        gatherer.Append($"&{prefix}{p.Name}={item.ToString("yyyy-MM-dd")}");

                else if (p.PropertyType.IsArray)
                    foreach (var item in value as Array)
                        gatherer.Append($"&{prefix}{p.Name}={item}");

                else if (p.PropertyType == typeof(string))
                    gatherer.Append($"&{prefix}{p.Name}={value}");

                else if (p.PropertyType == typeof(DateTime) && !value.Equals(Activator.CreateInstance(p.PropertyType))) // is not default 
                    gatherer.Append($"&{prefix}{p.Name}={((DateTime)value).ToString("yyyy-MM-dd")}");

                else if (p.PropertyType.IsValueType && !value.Equals(Activator.CreateInstance(p.PropertyType))) // is not default 
                    gatherer.Append($"&{prefix}{p.Name}={value}");


                else if (p.PropertyType.IsClass)
                    gatherer.Append(value.ToQueryStringBuilder($"{prefix}{p.Name}."));
            }
        }

        return gatherer;
    }
}

Un exemple d'utilisation de la solution :

 string queryString = new
{
    date = new DateTime(2020, 1, 1),
    myClass = new MyClass
    {
        FirstName = "john",
        LastName = "doe"
    },
    myArray = new int[] { 1, 2, 3, 4 },
}.ToQueryString();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X