Сериализация объекта в строку параметра URL - включая свойства вложенных объектов - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть класс, который содержит свойство, тип которого является другим классом. Например:

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

Как мне этого добиться?


Я нашел ответы на подобные вопросы, однако они не поддерживают вложенные классы.

Потенциальный ответ 1 Потенциальный ответ 2

Ответы [ 2 ]

0 голосов
/ 23 февраля 2020

Согласно @AdrianoRepetti Comment, вы просто проверите, является ли свойство nested или нет.

Следующий код дает ожидаемый результат:

1 - Получить тип Outer класс и вызывающая рекурсивная функция GetRequestFromObject

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

Type type = typeof(Outer);

string request = GetRequestFromObject<Outer>(type.GetProperties(), toSerialise);

Console.WriteLine(request);

2 - GetRequestFromObject Определение

private static string GetRequestFromObject<T>(PropertyInfo[] propertyInfos, T obj )
{
    string request = string.Empty;
    foreach(PropertyInfo propertyInfo in propertyInfos)
    {
        if (propertyInfo.PropertyType.IsNested)
        {
            object nestedObj = propertyInfo.GetValue(obj, null);
            request += GetRequestFromObject(propertyInfo.PropertyType.GetProperties(), nestedObj);
        }
        else
        {
            request += $"&{propertyInfo.Name}={propertyInfo.GetValue(obj, null)}";
        }
    }

    return request;
}

3 - Результат

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

Надеюсь, это поможет вам.

0 голосов
/ 21 февраля 2020

У нас была такая же проблема с состоянием клиента URL-адреса обратного вызова в Oauth2, поскольку 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. Отправить base64string в URL как параметр данных
  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==

Url:

&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 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...