3

我试图将我的应用程序中的一些类/对象转换为查询字符串,例如:

public class LoginRequest : BaseRequest
{
    public string username { get; set; }
    public string password { get; set; }
    public otherclass d { get; set; }
}

public class otherclass
{
    public string a { get; set; }
    public string b { get; set; }
}

然后会变成:

username=test&password=p&a=123&b=123

我通过以下功能实现

private string ObjectToQueryString<T>(T obj) where T: class {
    StringBuilder sb = new StringBuilder();
    Type t = obj.GetType();

    var properties = t.GetProperties();
    foreach (PropertyInfo p in properties)
    {
        if (p.CanRead)
        {
            var indexes = p.GetIndexParameters();
            if (indexes.Count() > 0)
            {
                var pp = p.GetValue(obj, new object[] { 1 });
                sb.Append(ObjectToQueryString(pp));
            }
            else
            {

                //I dont think this is a good way to do it
                if (p.PropertyType.FullName != p.GetValue(obj, null).ToString())
                {
                    sb.Append(String.Format("{0}={1}&", p.Name, HttpUtility.UrlEncode(p.GetValue(obj, null).ToString())));
                }
                else
                {
                    sb.Append(ObjectToQueryString(p.GetValue(obj, null)));
                }
            }
        }
    }

    return sb.ToString().TrimEnd('&');
}

但如果我将一个列表传递给函数,它还将包括计数和容量属性以及其他我不想要的东西。说它的清单

List<otherclass>()

干杯

4

3 回答 3

3

对我来说似乎很简单,检查该类是 IEnumerable 还是 IEnumerator,如果是,则枚举它(而不是反映该特定类)。如果您解释您希望我们如何处理此类结果,将会有所帮助。

//username=bob&password=123&a=Cheese&b=Chocolate&a=Cat&b=Dog

public class LoginRequest
{
    public string username { get; set; }
    public string password { get; set; }
    public List<OtherClass> d { get; set; }
}

public class OtherClass
{
    public string a { get; set; }
    public string b { get; set; }
}

static void Main(string[] args)
{
    var request = new LoginRequest
    {
        username = "bob",
        password = "123",
        d = new List<OtherClass> { new OtherClass { a = "Cheese", b = "Chocolate" } ,
        new OtherClass { a = "Cat", b = "Dog" } }
    };

    Console.WriteLine(ObjectToQueryString(request));
    Console.ReadLine();
}

private static string ObjectToQueryString<T>(T obj) where T : class
{
    StringBuilder sb = new StringBuilder();

    IEnumerable data = obj as IEnumerable ?? new[] { obj };

    foreach (var datum in data)
    {
        Type t = datum.GetType();
        var properties = t.GetProperties();
        foreach (PropertyInfo p in properties)
        {
            if (p.CanRead)
            {
                var indexes = p.GetIndexParameters();
                if (indexes.Count() > 0)
                {
                    var pp = p.GetValue(datum, new object[] { 1 });
                    sb.Append(ObjectToQueryString(pp));
                }
                else if (typeof(IEnumerable).IsAssignableFrom(p.PropertyType) && p.PropertyType  != typeof(string))
                {
                    sb.Append(ObjectToQueryString(p.GetValue(datum)));
                }
                else
                {

                    //I dont think this is a good way to do it
                    if (p.PropertyType.FullName != p.GetValue(datum, null).ToString())
                    {
                        //sb.Append(String.Format("{0}={1}&", p.Name, HttpUtility.UrlEncode(p.GetValue(datum, null).ToString())));
                        sb.Append(String.Format("{0}={1}&", p.Name, p.GetValue(datum, null).ToString()));
                    }
                    else
                    {
                        sb.Append(ObjectToQueryString(p.GetValue(datum, null)));
                    }
                }
            }
        }
    }
    return sb.ToString().TrimEnd('&');
}
于 2013-09-12T00:03:15.933 回答
3

我不明白这一点,你为什么要这么复杂?

public class LoginRequest : BaseRequest
{
    public string username { get; set; }
    public string password { get; set; }
    public otherclass d { get; set; }

    public String getQueryString(){
      return "username="+this.username+"&password="+this.password+"&a="+this.d.a+"&b="+this.d.b;
    }
}

public class otherclass
{
    public string a { get; set; }
    public string b { get; set; }
}

...还是您在问题中遗漏了什么?

于 2013-09-12T00:06:27.390 回答
0

使用 GetProperties() 的 BindingFlags 参数

http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags%28v=vs.71%29.aspx

GetProperties(BindingFlags.DeclaredOnly | ...)

将其结果限制为您的类型声明的属性。

于 2013-09-12T00:09:48.117 回答