ASP.NET MVC - 如何 "reverse" 模型绑定将 C# 模型转换回查询字符串表示

ASP.NET MVC - How to "reverse" model binding to convert a C# model back to a query string representation

我在客户端有一个自定义 javascript,用于构建查询字符串并传递给我的 asp.net-mvc 控制器

   var templateQueryString = BuildTemplate();

    $.ajax({
      url: '/MyController/Save?' + templateQueryString,
      type: 'post',
      dataType: 'json',
      success: function (data) {
      }
    }

在我的控制器上,所有属性都利用模型绑定,因此它作为服务器端的单个对象出现。注意:这是一个非常复杂的对象,包含数组和子对象数组:

public ActionResult Save(MyTemplate template)
{
}

现在的问题是我需要能够在客户端将我的 C# 对象转换回代表 "myTemplateQueryString" 的字符串。

是否有任何推荐的方法来获取对象并进行 "reverse" 模型绑定。他们在这里的关键是它生成一个字符串,我可以在将来再次用作查询字符串以传递到另一个 asp.ent-mvc 控制器操作。

这是我在本地存储的查询字符串的示例:

  <input type="hidden" value="showIds=false&amp;showRisks=false&
  amp;statusIds=2&amp;statusIds=1&amp;statusIds=6&amp;statusIds=8&
  amp;statusIds=3&amp;statusIds=9&amp;showCompleted=0" 
  name="filterQueryString" id="filterQueryString">

正如@haim770 所说,如果您在请求有效负载中使用 JSON 而不是查询字符串来将您的复杂对象传递给服务器,那将会更容易。

关于从模型创建查询字符串,据我所知,没有内置方法可以执行类似的操作或任何推荐的方法。一个明显的解决方案是使用 reflection 并从您的属性构建查询字符串。

假设您的 BuildTemplate class 看起来像:

public class BuildTemplate
{
    public bool ShowIds { get; set; }
    public bool ShowRisks { get; set; }
    public bool ShowCompleted { get; set; }
    public int[] StatusIds { get; set; }
}

您可以开发一个扩展方法来将任何对象转换为 QueryString。您可以从以下一些初始代码开始:

public static class ObjectExtensions
{
    public static string ToQueryString(this Object obj)
    {
        var keyPairs = obj.GetType().GetProperties().Select(p =>
            new KeyValuePair<string, object>(p.Name.ToLower(), p.GetValue(obj, null)));

        var arr = new List<string>();

        foreach (var item in keyPairs)
        {
            if (item.Value is IEnumerable && !(item.Value is String))
            {
                foreach (var arrayItem in (item.Value as IEnumerable))
                {
                    arr.Add(String.Format("{0}={1}", item.Key, arrayItem.ToString().ToLower()));
                }
            }
            else
                arr.Add(String.Format("{0}={1}", item.Key, item.Value.ToString().ToLower()));
        }

        return "?" + String.Join("&", arr);
    }
}

然后您可以轻松地在任何对象上调用此代码以生成查询字符串:

var person = new BuildTemplate() { StatusIds = new []{ 1, 5, 8, 9 }, ShowRisks = true };

var queryString = person.ToQueryString();

这将生成如下查询字符串:

"?showids=false&showrisks=true&showcompleted=false&statusids=1&statusids=5&statusids=8&statusids=9"

此查询字符串应该可以与 BuildTemplate class.

的默认模型绑定器一起正常工作