GET 请求的 List<X> 参数的 MVC 自定义序列化?

MVC custom serialization of List<X> parameter for GET request?

我想将请求更改为 GET 而不是 POST,以便用户可以共享生成的 URL。
当前系统使用普通表单提交,并利用表单提交和自定义对象列表的 MVC ActionResult 之间的自动序列化。

例如

<form action="/MyPage">
  <input type="hidden" id="MyThings_0__Value" name="MyThings[0].Value">
  <input type="hidden" id="MyThings_0__Flag" name="MyThings[0].Flag">

  <input type="hidden" id="MyThings_1__Value" name="MyThings[1].Value">
  <input type="hidden" id="MyThings_1__Flag" name="MyThings[1].Flag">
</form>

但是这样做会导致生成的GET字符串过长和复杂。这很糟糕,因为 MyThings 列表最多可以包含 10 个项目。

http://myurl.com/MyPage?MyThings%5B0%5D.Value=ThisIsValue1&MyThings%5B0%5D.Flag=1&MyThings%5B1%5D.Value=ThisIsValue2&MyThings%5B1%5D.Flag=2

我希望该字符串看起来更加用户友好。类似于:

http://myurl.com/MyPage?MyThings=ThisIsValue1-1,ThisIsValue2-2

这可以通过自定义序列化来完成吗?如果是这样,我将如何实施它?

我的模型和 ActionResult:

namespace MyNamespace {

    public class MyThing {
        public string Value { get; set; }
        public int Flag { get; set; }
    }

    public class Filter {
        public string CustomAttribute1 { get; set; }
        public string CustomAttribute2 { get; set; }
        public string CustomAttribute3 { get; set; }

        public List<MyThing> MyThings { get; set; } = new List<MyThing>();
    }

    public ActionResult MyPage(Filter filter) {
        MyModel model = StaticMethod.GetMyModel(filter);
        return View(model);
    }

}

最后我决定不使用自定义 URL 序列化,而是使用辅助方法在 C# 模型中向后和向前转换为 string/class。

public class Filter {

    public string MyThing { get; set; }

    public List<MyThingClass> MyThings {
        get {
            if (this._myThings == null) { // Default to Query string
                this._myThings = ToQueryList(this.MyThing);
            }
            return this._myThings;
        }
        set {
            this.MyThing = ToQueryString(value); // Automatically assign QueryString to serialized QueryItems on set
            this._myThings = value;
        }
    }
    private List<MyThingClass> _myThings { get; set; }

    public static List<MyThingClass> ToQueryList(string queryString) {
        return queryString.Split(',').Select(x => MyThingClass.FromString(x)).ToList();
    }
    public static string ToQueryString(List<MyThingClass> myThings) {
        return string.Join(",", myThings.Select(x => x.ToString()));
    }
}



public class MyThingClass {

    public string Value { get; set; }

    public int Flag { get; set; }

    /// <summary>Converts a QueryItem object to a serialized object ready for the QueryString.</summary>
    public override string ToString() {
        return string.Concat(this.Value, "-", this.Flag);
    }

    public static MyThingClass FromString(string value) {
        var v = value.Split('-');
        return new MyThingClass() {
            Value = v[0],
            Flag = Convert.ToInt32(v[1])
        };
    }
}