简体   繁体   中英

Converting an anonymous object's properties and values to a Dictionary

I am creating a library for an existing API. I currently have QueryParameter classes for each request class. The QueryParameter classes are simple but they do vary (not all requests take the same query parameters).

Here is an example of a QueryParameter class:

public class ApiRequestAQueryParameters
{
    public string Name { get; set; }
    public int Start { get; set; }
    public int Stop { get; set; }
}

I am interested in a way to convert a class like this into a Dictionary that I can feed to our Web client. I am hoping to have a reusable method like:

private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
// perform conversion
}

This way I won't have to pull out the QueryParameter properties for each request (there will be dozens of requests)

The reason that I am using QueryParameter classes instead of making QueryParameter a Dictionary property of each API request class is to be developer friendly. I want to make it so that others can build these API requests by looking at the classes.

There are 2 ways: 1) use reflection and 2) serialize to json and back.

Here is the 1st method:

private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
    var res = new Dictionary<string, string>();
    var props = queryParametersObject.GetType().GetProperties();
    foreach (var prop in props)
    {
        res[prop.Name] = prop.GetValue(queryParametersObject).ToString();
    }
    return res;
}

You can do something like this:

private Dictionary<string, string> GenerateQueryParameters(object queryParameters)
{
    var startStop = new StartStop() { Start = queryParameters.Start, Stop = queryParameters.Stop};
    var result = new Dictionary<string, string>();
    result.Add(queryParameters.Name, startStop);
    return result;
}

public class StartStop
{
    public int Start { get; set; }
    public int Stop { get; set; }
}

This may be the perfect case to utilize ExpandoObjects. An ExpandoObject is a dynamic type, whose properties can be created at run time. ExpandoObject implements IDictionary < string, object > so it's easy to convert to a Dictionary < string, object > .

In the example below, an ExpandoObject is created and converted to a Dictionary < string, object > and then converted to a Dictionary < string, string >.

dynamic apiVar = new ExpandoObject();
apiVar.Name = "Test";
apiVar.Start = 1;
apiVar.Stop = 2;

var iDict = (IDictionary<string, object>) apiVar;
/* if you can utilize a Dictionary<string, object> */
var objectDict = iDict.ToDictionary(i => i.Key, i => i.Value);
/* if you need a Dictionary<string, string> */
var stringDict = iDict.ToDictionary( i=>i.Key, i=> i.Value.ToString());

There are also different ways of setting properties on an ExpandoObject. Below is an example of setting a property by a variable name.

dynamic apiVar = new ExpandoObject();
var propertyName = "Name";
apiVar[propertyName] = "Test";
propertyName = "Start";
apiVar[propertyName] = 1;
propertyName = "Stop";
apiVar[propertyName] = 2;

I always reuse the RouteValueDictionary class for this. It has a constructor that accepts any object and the class itself implements IDictionary.

It's available in the System.Web dll

private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
    return new RouteValueDictionary(queryParametersObject).ToDictionary(d => d.Key, d => Convert.ToString(d.Value));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM