如何将对象序列化为查询string格式?

如何将对象序列化为查询string格式? 我似乎无法在Google上find答案。 谢谢。

这里是我将作为例子序列化的对象。

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; } } 

我99%肯定没有内置的实用工具方法。 这不是一个非常常见的任务,因为Web服务器通常不会响应 URLEncoded键/值string。

你如何看待混合reflection和LINQ? 这工作:

 var foo = new EditListItemActionModel() { Id = 1, State = 26, Prefix = "f", Index = "oo", ParentID = null }; var properties = from p in foo.GetType().GetProperties() where p.GetValue(foo, null) != null select p.Name + "=" + HttpUtility.UrlEncode(p.GetValue(foo, null).ToString()); // queryString will be set to "Id=1&State=26&Prefix=f&Index=oo" string queryString = String.Join("&", properties.ToArray()); 

更新:

要编写一个返回任何1深对象的QueryString表示的方法,可以这样做:

 public string GetQueryString(object obj) { var properties = from p in obj.GetType().GetProperties() where p.GetValue(obj, null) != null select p.Name + "=" + HttpUtility.UrlEncode(p.GetValue(obj, null).ToString()); return String.Join("&", properties.ToArray()); } // Usage: string queryString = GetQueryString(foo); 

你也可以把它做成一个扩展方法,而不需要额外的工作

 public static class ExtensionMethods { public static string GetQueryString(this object obj) { var properties = from p in obj.GetType().GetProperties() where p.GetValue(obj, null) != null select p.Name + "=" + HttpUtility.UrlEncode(p.GetValue(obj, null).ToString()); return String.Join("&", properties.ToArray()); } } // Usage: string queryString = foo.GetQueryString(); 

基于其他评论的好主意,我做了一个通用的扩展方法.ToQueryString(),它可以用在任何对象上。

 public static class UrlHelpers { public static string ToQueryString(this object request, string separator = ",") { if (request == null) throw new ArgumentNullException("request"); // Get all properties on the object var properties = request.GetType().GetProperties() .Where(x => x.CanRead) .Where(x => x.GetValue(request, null) != null) .ToDictionary(x => x.Name, x => x.GetValue(request, null)); // Get names for all IEnumerable properties (excl. string) var propertyNames = properties .Where(x => !(x.Value is string) && x.Value is IEnumerable) .Select(x => x.Key) .ToList(); // Concat all IEnumerable properties into a comma separated string foreach (var key in propertyNames) { var valueType = properties[key].GetType(); var valueElemType = valueType.IsGenericType ? valueType.GetGenericArguments()[0] : valueType.GetElementType(); if (valueElemType.IsPrimitive || valueElemType == typeof (string)) { var enumerable = properties[key] as IEnumerable; properties[key] = string.Join(separator, enumerable.Cast<object>()); } } // Concat all key/value pairs into a string separated by ampersand return string.Join("&", properties .Select(x => string.Concat( Uri.EscapeDataString(x.Key), "=", Uri.EscapeDataString(x.Value.ToString())))); } } 

如果它们只包含基元或string,它也可以用于具有Arraytypes和generics列表属性的对象。

试试看,欢迎注释: 使用Reflection将对象序列化为查询string

基于stream行的答案,我需要更新代码以支持数组。 共享实施:

 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()); } 
 public static class UrlHelper { public static string ToUrl(this Object instance) { var urlBuilder = new StringBuilder(); var properties = instance.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); for (int i = 0; i < properties.Length; i++) { urlBuilder.AppendFormat("{0}={1}&", properties[i].Name, properties[i].GetValue(instance, null)); } if (urlBuilder.Length > 1) { urlBuilder.Remove(urlBuilder.Length - 1, 1); } return urlBuilder.ToString(); } } 

这是我写的,你需要的东西。

  public string CreateAsQueryString(PageVariables pv) //Pass in your EditListItemActionModel instead { int i = 0; StringBuilder sb = new StringBuilder(); foreach (var prop in typeof(PageVariables).GetProperties()) { if (i != 0) { sb.Append("&"); } var x = prop.GetValue(pv, null).ToString(); if (x != null) { sb.Append(prop.Name); sb.Append("="); sb.Append(x.ToString()); } i++; } Formating encoding = new Formating(); // I am encoding my query string - but you don''t have to return "?" + HttpUtility.UrlEncode(encoding.RC2Encrypt(sb.ToString())); } 

面对类似的情况,我做了,是XML序列化的对象,并传递它作为查询string参数。 这种方法的困难是,尽pipe编码,接收forms抛出exception说“潜在危险的请求…”。 我得到的方式是encryption序列化的对象,然后编码传递它作为查询string参数。 这反过来又使查询string防篡改(奖金stream入HMAC的领土)!

FormA XML序列化对象>encryption序列化的string>编码>传递为查询stringFormB FormB解密查询参数值(如request.querystring也解码)>使用XmlSerializer反序列化生成的XMLstring。

我可以根据要求将我的VB.NET代码分享给howIdidit-at-applecart-dot-net

我正在寻找一个Windows 10(UWP)应用程序的解决scheme。 采用Davebuild议的Relection方法,在添加Microsoft.AspNet.WebApi.Client Nuget包之后,我使用了下面的代码来处理属性值的Url编码:

  private void AddContentAsQueryString(ref Uri uri, object content) { if ((uri != null) && (content != null)) { UriBuilder builder = new UriBuilder(uri); HttpValueCollection query = uri.ParseQueryString(); IEnumerable<PropertyInfo> propInfos = content.GetType().GetRuntimeProperties(); foreach (var propInfo in propInfos) { object value = propInfo.GetValue(content, null); query.Add(propInfo.Name, String.Format("{0}", value)); } builder.Query = query.ToString(); uri = builder.Uri; } }