I have the following anonymous type:
new {data1 = \"test1\", data2 = \"sam\", data3 = \"bob\"}
I need a method that will take this in, and
@kbrimington's solution makes a nice extension method - my my case returning a HtmlString
public static System.Web.HtmlString ToHTMLAttributeString(this Object attributes)
{
var props = attributes.GetType().GetProperties();
var pairs = props.Select(x => string.Format(@"{0}=""{1}""",x.Name,x.GetValue(attributes, null))).ToArray();
return new HtmlString(string.Join(" ", pairs));
}
I'm using it to drop arbitrary attributes into a Razor MVC view. I started with code using RouteValueDictionary and looping on the results but this is much neater.
using Newtonsoft.Json;
var data = new {data1 = "test1", data2 = "sam", data3 = "bob"};
var encodedData = new FormUrlEncodedContent(JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonConvert.SerializeObject(data))
I did something like this:
public class ObjectDictionary : Dictionary<string, object>
{
/// <summary>
/// Construct.
/// </summary>
/// <param name="a_source">Source object.</param>
public ObjectDictionary(object a_source)
: base(ParseObject(a_source))
{
}
/// <summary>
/// Create a dictionary from the given object (<paramref name="a_source"/>).
/// </summary>
/// <param name="a_source">Source object.</param>
/// <returns>Created dictionary.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="a_source"/> is null.</exception>
private static IDictionary<String, Object> ParseObject(object a_source)
{
#region Argument Validation
if (a_source == null)
throw new ArgumentNullException("a_source");
#endregion
var type = a_source.GetType();
var props = type.GetProperties();
return props.ToDictionary(x => x.Name, x => x.GetValue(a_source, null));
}
}
If you are using .NET 3.5 SP1 or .NET 4, you can (ab)use RouteValueDictionary for this. It implements IDictionary<string, object>
and has a constructor that accepts object
and converts properties to key-value pairs.
It would then be trivial to loop through the keys and values to build your query string.
Here is how they do it in RouteValueDictionary:
private void AddValues(object values)
{
if (values != null)
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
{
object obj2 = descriptor.GetValue(values);
this.Add(descriptor.Name, obj2);
}
}
}
Full Source is here: http://pastebin.com/c1gQpBMG
This takes just a tiny bit of reflection to accomplish.
var a = new { data1 = "test1", data2 = "sam", data3 = "bob" };
var type = a.GetType();
var props = type.GetProperties();
var pairs = props.Select(x => x.Name + "=" + x.GetValue(a, null)).ToArray();
var result = string.Join("&", pairs);