Search code examples
jsonf#json.net

Deserializing JSON: The input is not a valid Base-64 string as it contains a non-base 64 character


Problem:

I just can't figure out what's wrong with the JSON below.

Error:

'The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.'

Test:

I ran a JSON validation tool on it and it passed as valid JSON. However, I continue to receive a base-64 conversion error.

{
  "Courier": {
    "CourierId": "e168d837-0f0e-4f61-8a3d-725b53d11277",
    "Name": "Jeremy Bot",
    "ProfileImage": "undefined_image",
    "LastLocation": {
      "Latitude": 25.87427,
      "Longitude": -80.12173
    },
    "IsSubscribed": true,
    "Timestamp": "2020-04-11T19:11:21.1821483-04:00"
  },
  "Request": {
    "RequestId": "78d31dab-e631-4f95-aa31-d95b218a1850",
    "Customer": {
      "CustomerId": "some_customer_id",
      "Name": "John Doe",
      "Location": {
        "Latitude": 25.87427,
        "Longitude": -80.12173
      },
      "Phone": "(XXX-XXX-XXXX)"
    },
    "Carriers": {
      "Restaurants": [],
      "Stores": []
    }
  },
  "ETA": "30 minutes"
}

Test 2:

I thought that the cause could be a negative number in my JSON.

However, the following didn't work:

let handleNegativeValues = JsonSerializerSettings(FloatParseHandling=FloatParseHandling.Decimal)

let payload = JsonConvert.DeserializeObject<'T>(json, handleNegativeValues)

Cause:

Here's the code that I execute which results in the error:

let payload = JsonConvert.DeserializeObject<'T>(json)

Appendix:

Here's the root type that I'm trying to deserialize to:

[<DataContract>]
type CourierAcceptedSubmission = {

    [<field: DataMember(Name="Courier")>]
    Courier  : Courier

    [<field: DataMember(Name="Request")>]
    Request  : Request

    [<field: DataMember(Name="ETA")>]
    ETA  : string
}

Here's the type that contains ProfileImage:

[<DataContract>]
type Courier = {

    [<field: DataMember(Name="CourierId")>]
    CourierId    : string

    [<field: DataMember(Name="Name")>]
    Name         : string

    [<field: DataMember(Name="ProfileImage")>]
    ProfileImage : string

    [<field: DataMember(Name="LastLocation")>]
    LastLocation : Coordinate

    [<field: DataMember(Name="IsSubscribed")>]
    IsSubscribed : bool

    [<field: DataMember(Name="Timestamp")>]
    Timestamp    : DateTime
}

Solution

  • Json.Net handles byte arrays by automatically converting them to and from base-64 encoded strings. So if you are deserializing JSON into a class that has a property declared as byte[] but the corresponding string value in the JSON is not base-64 encoded, for example "undefined_image", that will cause the error you are seeing.

    The easiest fix is to change the type of the offending property from byte[] to string. However, if you have a situation where the JSON will sometimes contain valid base-64 strings and sometimes not, and you do want it to be a byte[] to handle the data for the valid case, you would need to create a custom JsonConverter to handle that property.