【问题标题】:Serialise an object to URL parameter string - Including properties from nested objects将对象序列化为 URL 参数字符串 - 包括来自嵌套对象的属性
【发布时间】:2020-02-21 12:14:01
【问题描述】:

我有一个类,其中包含一个类型是另一个类的属性。例如:

public class Outer
{
    public string SomeStringProperty { get; set; }
    public Inner SomeClassProperty { get; set; }
}

public class Inner
{
    public string InnerProperty1 { get; set; }
    public string InnerProperty2 { get; set; }
}

我想将Outer 类的实例转换为URL 查询字符串,并包含嵌套Inner 类的属性。

例如,给定Outer的实例,如:

Outer toSerialise = new Outer 
{
    SomeStringProperty = "MyOuterValue",
    SomeClassProperty = new Inner
    {
        InnerProperty1 = "MyInnerValue1",
        InnerProperty2 = "MyInnerValue2"
    }
};

我想把它转换成一个字符串:

&SomeStringProperty=MyOuterValue&InnerProperty1=MyInnerValue1&InnerProperty2=MyInnerValue2

我怎样才能做到这一点?


我找到了类似问题的答案,但它们似乎不支持嵌套类。

Potential answer 1 Potential answer 2

【问题讨论】:

  • 提示:当您拥有PropertyInfo 时,请检查PropertyType...如果它不是String 也不是IsPrimitive,则递归调用相同的函数来累积属性值.
  • @AdrianoRepetti 好点,谢谢!我想知道使用 stringIsPrimitive 的可靠性如何 - 看起来 DateTime 是 not 原始的,但应该属于这一类。不知道还有没有这样的……?
  • 要支持更多数据类型,您必须处理每一种数据类型(繁琐)或检查对象是否实现IConvertible(用于转换为字符串),但仍然存在一些边缘情况。

标签: c# serialization query-string


【解决方案1】:

我们在 Oauth2 中回调 url 的客户端状态存在同样的问题,因为回调 url 也有 & 符号

http://.......?param=123&param2=456&state=?id=1&name=test

我们只是将回调 url 转换为 Base64 编码的字符串并在服务本身进行解码。

http://.......?param=123&param2=456&state=P2lkPTEmbmFtZT10ZXN0

修复:

  1. 将您的类实例编码为 json
  2. 将json编码为base64string
  3. 在 url 中发送 base64string 作为数据参数
  4. 解码 base64 并将 json 映射到您的 api 中的模型中。

JSON:

 { "menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}

Base64:

eyJtZW51IjogewogICJpZCI6ICJmaWxlIiwKICAidmFsdWUiOiAiRmlsZSIsCiAgInBvcHVwIjogewogICAgIm1lbnVpdGVtIjogWwogICAgICB7InZhbHVlIjogIk5ldyIsICJvbmNsaWNrIjogIkNyZWF0ZU5ld0RvYygpIn0sCiAgICAgIHsidmFsdWUiOiAiT3BlbiIsICJvbmNsaWNrIjogIk9wZW5Eb2MoKSJ9LAogICAgICB7InZhbHVlIjogIkNsb3NlIiwgIm9uY2xpY2siOiAiQ2xvc2VEb2MoKSJ9CiAgICBdCiAgfQp9fQ==

网址:

&data=eyJtZW51IjogewogICJpZCI6ICJmaWxlIiwKICAidmFsdWUiOiAiRmlsZSIsCiAgInBvcHVwIjogewogICAgIm1lbnVpdGVtIjogWwogICAgICB7InZhbHVlIjogIk5ldyIsICJvbmNsaWNrIjogIkNyZWF0ZU5ld0RvYygpIn0sCiAgICAgIHsidmFsdWUiOiAiT3BlbiIsICJvbmNsaWNrIjogIk9wZW5Eb2MoKSJ9LAogICAgICB7InZhbHVlIjogIkNsb3NlIiwgIm9uY2xpY2siOiAiQ2xvc2VEb2MoKSJ9CiAgICBdCiAgfQp9fQ==

替代方案:

如果你必须使用这种查询格式,那么你也可以使用委托类型

Outer toSerialise = new Outer 
{
    SomeStringProperty = "MyOuterValue",
    SomeClassProperty = new Inner
    {
        InnerProperty1 = "MyInnerValue1",
        InnerProperty2 = "MyInnerValue2"
    }
};

var queryObject = new { toSerialise.SomeStringProperty, toSerialise .Inner.InnerProperty1, toSerialise.Inner.InnerProperty2 }

【讨论】:

  • 这似乎是一个完全不同的问题的解决方案!
  • 对于问题“我想将 Outer 类的实例转换为 URL 查询字符串,并包含来自嵌套 Inner 类的属性。” -> Json 包含嵌套内部类默认的属性。为了能够以 url base64 编码发送 json 也解决了这个问题。在 url 的目标站点,他可以解码 base64 并将 json 数据映射为类模型,这解决了所有问题。我不认为这是一个不同的问题。
  • +1 用于跳出框框思考。问题在于,要使其正常工作,您需要控制接收请求的 API,但情况可能并非总是如此。它还涉及多层序列化/反序列化,这可能会对性能产生影响。虽然我没有尝试过你的方法,但我确实希望它能够工作,但这远非理想的解决方案。
猜你喜欢
  • 1970-01-01
  • 2020-06-09
  • 2011-12-21
  • 1970-01-01
  • 2018-09-05
  • 1970-01-01
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
相关资源
最近更新 更多