-1

Here is the json:

[
    {
        "FirstName": "bob",
        "LastName": "ob",
        "Country": "vxv",
        "CityOrTown": "aaaaa",
        "Line1": "3EF1A60C-4en St.dsadsa",
        "PostalCode": "91106",
        "BirthDay": "07",
        "BirthMonth": "06",
        "BirthYear": "2000"
    },
    {
        "FirstName": "bbb",
        "LastName": "bbb",
        "Country": "bbb",
        "CityOrTown": "bbb",
        "Line1": "bbb",
        "PostalCode": "bbb",
        "BirthDay": "06",
        "BirthMonth": "06",
        "BirthYear": "2000"
    }
]

Here is object I want to convert this json into:

namespace Stripe
{
    public class StripeAccountAdditionalOwner : INestedOptions
    {
        public StripeAccountAdditionalOwner();

        [JsonProperty("[address][city]")]
        public string CityOrTown { get; set; }

        [JsonProperty("[address][country]")]
        public string Country { get; set; }

        [JsonProperty("[address][line1]")]
        public string Line1 { get; set; }

        [JsonProperty("[address][line2]")]
        public string Line2 { get; set; }

        [JsonProperty("[address][postal_code]")]
        public string PostalCode { get; set; }

        [JsonProperty("[address][state]")]
        public string State { get; set; }

        [JsonProperty("[dob][day]")]
        public int? BirthDay { get; set; }

        [JsonProperty("[dob][month]")]
        public int? BirthMonth { get; set; }

        [JsonProperty("[dob][year]")]
        public int? BirthYear { get; set; }

        [JsonProperty("[first_name]")]
        public string FirstName { get; set; }

        [JsonProperty("[last_name]")]
        public string LastName { get; set; }

        [JsonProperty("verification[document]")]
        public string VerificationDocument { get; set; }
    }
}

Here is code I am using in controller:

List<StripeAccountAdditionalOwner> AdditionalOwners = JsonConvert.DeserializeObject<List<StripeAccountAdditionalOwner>>(requestData.CompanyOwners);

requestData.CompanyOwners is the json array of objects.

Note: It is not giving me any errors. There is no missing references, and it passes through this line of code flawlessly, however all values remain null. Thanks in advance guys, I really appreciate.

maccettura
  • 10,514
  • 3
  • 28
  • 35
user10001850
  • 13
  • 1
  • 4
  • 1
    Look up the documentation for the `JsonProperty` attribute (https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonPropertyAttribute.htm). I think you misunderstand what the attribute really does. –  Jun 27 '18 at 21:00
  • @elgonzo I was just ignoring that actually. I was thinking I could just use the same exact spelling of the class properties in the json and then convert in c# – user10001850 Jun 27 '18 at 21:03
  • 1
    Yeah your `[JsonProperty()]` attributes make no sense. Only use `JsonProperty` when the json key is different from your property name. The serializer is not case sensitive, so if your property in JSON is `someKey` and your C# propert is `SomeKey` that will be fine – maccettura Jun 27 '18 at 21:03
  • Well, but your JsonProperty attributes instruct the (de)serializer to **NOT** use the class property names but instead use the names provided with the attributes... ;-) –  Jun 27 '18 at 21:04
  • @maccettura That entire class is actually from stripe – user10001850 Jun 27 '18 at 21:04
  • @user10001850 well then they dont know what they are doing haha – maccettura Jun 27 '18 at 21:04
  • @elgonzo Ok thanks! Do you recommend me change the json array attribute names, however in the class the JsonProperty values that have two brackets are confusing... although i am thinking this means for example the [dob] key has a value of an object with 3 keys within (day, month, year) Correct? – user10001850 Jun 27 '18 at 21:06
  • 1
    @user10001850 just remove the `[JsonProperty]` attributes from all properties _unless_ the name in C# is different from the name in JSON. The documentation elgonzo linked will explain all this – maccettura Jun 27 '18 at 21:06
  • @maccettura I cannot this is some type of metadata file that the class is written in – user10001850 Jun 27 '18 at 21:07
  • @user10001850 so you cannot modify the `StripeAccountAdditionalOwner ` class? – maccettura Jun 27 '18 at 21:07
  • If it is not feasible remove the JsonProperty attributes, you could work around the problem by writing a custom contract resolver for the affected class(es). See here fore some example: https://stackoverflow.com/questions/20622492/how-to-ignore-jsonpropertypropertyname-somename-when-serializing-json As you can see in the example given in the answer to the Q i linked, such a contract resolver is pretty much type-agnostic, so you should be able to use it for most if not all Stripe classes that give you the same JsonProperty attribute problems. –  Jun 27 '18 at 21:10
  • 1
    The json you are showing is not what Stripe returns, and the class in your question is used internally inside `Stripe.NET` (with a custom JsonConverter) to deserialize their json into strongly typed objects. It is not clear **at all** what you are trying to achieve: do you want to deserialize Stripe responses or are you trying to create a different model (for a different purpose)? – Federico Dipuma Jun 27 '18 at 21:25
  • @FedericoDipuma What I am doing is: upon account creation phase user fills out form, GB requires company owners field which may include several people. I am grouping the 8 inputs from each owner in to the json object array, then passing it to controller after which it will be converted to this stripe class then sent to stripe. – user10001850 Jun 27 '18 at 21:29
  • 2
    Then create *another* class, which conforms with *your* json. What you copy/pasted cannot work in your situation. – Federico Dipuma Jun 27 '18 at 21:31
  • @FedericoDipuma If i try to do that I get a cannot implicitly convert message. Because this class is within another class StripeAccountLegalEntity – user10001850 Jun 27 '18 at 21:48

2 Answers2

0

Using [https://app.quicktype.io/#l=cs&r=json2csharp][1] able to generate below class for the JSON in the question

using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public partial class Welcome
{
    [JsonProperty("FirstName")]
    public string FirstName { get; set; }

    [JsonProperty("LastName")]
    public string LastName { get; set; }

    [JsonProperty("Country")]
    public string Country { get; set; }

    [JsonProperty("CityOrTown")]
    public string CityOrTown { get; set; }

    [JsonProperty("Line1")]
    public string Line1 { get; set; }

    [JsonProperty("PostalCode")]
    public string PostalCode { get; set; }

    [JsonProperty("BirthDay")]
    public string BirthDay { get; set; }

    [JsonProperty("BirthMonth")]
    public string BirthMonth { get; set; }

    [JsonProperty("BirthYear")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long BirthYear { get; set; }
}

public partial class Welcome
{
    public static Welcome[] FromJson(string json) => JsonConvert.DeserializeObject<Welcome[]>(json, QuickType.Converter.Settings);
}

public static class Serialize
{
    public static string ToJson(this Welcome[] self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}

internal static class Converter
{
    public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
        Converters = {
            new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
        },
    };
}

internal class ParseStringConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null) return null;
        var value = serializer.Deserialize<string>(reader);
        long l;
        if (Int64.TryParse(value, out l))
        {
            return l;
        }
        throw new Exception("Cannot unmarshal type long");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        if (untypedValue == null)
        {
            serializer.Serialize(writer, null);
            return;
        }
        var value = (long)untypedValue;
        serializer.Serialize(writer, value.ToString());
        return;
    }

    public static readonly ParseStringConverter Singleton = new ParseStringConverter();
}
Viju
  • 95
  • 1
  • 7
0

Use this as your model class

    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class JsonModel
    {
        [JsonProperty("FirstName")]
        public string FirstName { get; set; }

        [JsonProperty("LastName")]
        public string LastName { get; set; }

        [JsonProperty("Country")]
        public string Country { get; set; }

        [JsonProperty("CityOrTown")]
        public string CityOrTown { get; set; }

        [JsonProperty("Line1")]
        public string Line1 { get; set; }

        [JsonProperty("PostalCode")]
        public string PostalCode { get; set; }

        [JsonProperty("BirthDay")]
        public string BirthDay { get; set; }

        [JsonProperty("BirthMonth")]
        public string BirthMonth { get; set; }

        [JsonProperty("BirthYear")]

        public string BirthYear { get; set; }
    }

then do this in your main class

            var data = JsonConvert.DeserializeObject<JsonModel>(jsonstring);
            var country = data.Country;
            var birthday = data.BirthDay;
Tolulope
  • 488
  • 1
  • 5
  • 19