Десериализовать физически несовместимый JSON с моделью предметной области - PullRequest
0 голосов
/ 26 июня 2019

Я потребляю api отдыха, используя Restsharp. Ответ API имеет эту структуру.

{
    "resourceId": "0014b07-92sl-si90",
    "property": [
        {
            "name": "prop1",
            "value": "-1.0"
        },
        {
            "name": "prop2",
            "value": "0.0"
        },
        {
            "name": "prop3",
            "value": "1000.0"
        },
        {
            "name": "prop4",
            "value": "Microsoft Windows"
        },
        {
            "name": "prop5",
            "value": "42917.0"
        }]
}

Я хочу десериализовать этот ответ для этой доменной модели.

public class DomainModel 
{

    public double Prop1 {get; set;}

    public double Prop2 {get; set;}

    public double Prop3 {get; set;}

    public string Prop4 {get; set;}

}

Как видите, мне нужно только подмножество свойств ответа JSON, и ответ не может быть десериализован напрямую в объект домена.

Пожалуйста, как я могу решить эту проблему.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 26 июня 2019
public class DomainModel
{
    public string Prop1 { get; set; }

    public string Prop2 { get; set; }

    public string Prop3 { get; set; }

    public string Prop4 { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        string json = @"{
                        ""resourceId"": ""0014b07 - 92sl - si90"",
                        ""property"": [
                            {
                                ""name"": ""prop1"",
                                ""value"": ""-1.0""
                            },
                            {
                                ""name"": ""prop2"",
                                ""value"": ""0.0""
                            },
                            {
                                ""name"": ""prop3"",
                                ""value"": ""1000.0""
                            },
                            {
                                ""name"": ""prop4"",
                                ""value"": ""Microsoft Windows""
                            },
                            {
                                ""name"": ""prop5"",
                                ""value"": ""42917.0""
                            }]
                    }";
        var parsedJason = JObject.Parse(json);

        DomainModel result = new DomainModel();
        var jsonValues = parsedJason["property"].Select(x => ((JObject)x)).ToList();

        var props = typeof(DomainModel).GetProperties();
        jsonValues.ForEach(x =>
        {
            var jsonPropName = x.GetValue("name").ToString();
            var jsonPropValue = x.GetValue("value").ToString();

            var prop = props.Where(p => p.Name.ToUpper() == jsonPropName.Trim().ToUpper()).FirstOrDefault();
            if (prop != null)
                prop.SetValue(result, jsonPropValue, null);
        });
    }
}

enter image description here

1 голос
/ 26 июня 2019

Вы можете десериализовать ответ на этот класс:

public class MyResponse
{
    public string resourceId {get;set;}
    public List<MyProperty> property {get;set;}
}

public class MyProperty
{
    public string name {get;set;}
    public string value {get;set;}
}

Затем конвертируйте MyResponse в DomainModel:

DomainModel myDomainModel = new DomainModel();
myDomainModel.Prop1 = myResponse.property.Where(c=>c.name =="prop1").SingleOrDefault()?.value;
myDomainModel.Prop2 = myResponse.property.Where(c=>c.name =="prop3").SingleOrDefault()?.value;
myDomainModel.Prop2 = myResponse.property.Where(c=>c.name =="prop3").SingleOrDefault()?.value;
myDomainModel.Prop4 = myResponse.property.Where(c=>c.name =="prop4").SingleOrDefault()?.value;

Или встроить свою логику в пользовательский десериализатор .

1 голос
/ 26 июня 2019

Я бы использовал Json.NET и использовал атрибут JsonProperty, как описано в этом ответе: .NET NewtonSoft JSON десериализует карту с другим именем свойства

...