question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Transaction Status serialized as empty object

See original GitHub issue

General information

I’m noticing that if I return the Transaction object from one of my endpoints, the default .NET JSON serializer is serializing the status property it as an empty object, instead of the actual value.

  • SDK/Library version: 4.11.0
  • Environment: Sandbox
  • Language, language version, and OS: .NET Core 2.2, C#

Issue description

Returning the Braintree Transaction object from one of my .NET core endpoints, the Status property, as well as the Status properties in the Status History array are simply an empty objects. Here is an example:

{
    "id": "0fx5vfrv",
    "addOns": [],
    "amount": 10,
    "avsErrorResponseCode": null,
    "avsPostalCodeResponseCode": "A",
    "avsStreetAddressResponseCode": "A",
    "billingAddress": {
        "id": "5h",
        "customerId": null,
        "firstName": null,
        "lastName": null,
        "company": null,
        "streetAddress": null,
        "extendedAddress": null,
        "locality": null,
        "region": null,
        "postalCode": "94107",
        "countryCodeAlpha2": null,
        "countryCodeAlpha3": null,
        "countryCodeNumeric": null,
        "countryName": null,
        "createdAt": null,
        "updatedAt": null
    },
    "channel": null,
    "createdAt": "2019-05-22T20:22:47Z",
    "creditCard": {
        "bin": "401288",
        "cardholderName": null,
        "cardType": {},
        "createdAt": null,
        "customerId": null,
        "isDefault": null,
        "isVenmoSdk": false,
        "isExpired": null,
        "customerLocation": {},
        "lastFour": "1881",
        "uniqueNumberIdentifier": "906406403a9e494069f5b49983ca0f1a",
        "subscriptions": [],
        "token": "5xxx2q",
        "updatedAt": null,
        "billingAddress": {
            "id": null,
            "customerId": null,
            "firstName": null,
            "lastName": null,
            "company": null,
            "streetAddress": null,
            "extendedAddress": null,
            "locality": null,
            "region": null,
            "postalCode": null,
            "countryCodeAlpha2": null,
            "countryCodeAlpha3": null,
            "countryCodeNumeric": null,
            "countryName": null,
            "createdAt": null,
            "updatedAt": null
        },
        "expirationMonth": "12",
        "expirationYear": "2020",
        "prepaid": {},
        "payroll": {},
        "debit": {},
        "commercial": {},
        "healthcare": {},
        "durbinRegulated": {},
        "imageUrl": "https://assets.braintreegateway.com/payment_method_logo/visa.png?environment=sandbox",
        "verification": null,
        "accountType": null,
        "countryOfIssuance": "Unknown",
        "issuingBank": "Unknown",
        "productId": "Unknown",
        "expirationDate": "12/2020",
        "maskedNumber": "401288******1881"
    },
    "currencyIsoCode": "USD",
    "customerDetails": {
        "id": "149104609",
        "firstName": "Mark",
        "lastName": "Jones",
        "company": "Jones Co.",
        "email": "mark.jones@example.com",
        "phone": "614-555-1234",
        "fax": "419-555-1234",
        "website": "http://example.com"
    },
    "cvvResponseCode": "A",
    "descriptor": {
        "name": null,
        "phone": null,
        "url": null
    },
    "discounts": [],
    "disputes": [],
    "gatewayRejectionReason": {},
    "merchantAccountId": "skidata",
    "orderId": null,
    "planId": null,
    "processorAuthorizationCode": null,
    "processorResponseType": {},
    "processorResponseCode": "1002",
    "processorResponseText": "Processed",
    "processorSettlementResponseCode": null,
    "processorSettlementResponseText": null,
    "additionalProcessorResponse": null,
    "voiceReferralNumber": null,
    "purchaseOrderNumber": null,
    "recurring": null,
    "refundedTransactionId": "cch47ty3",
    "refundIds": [],
    "partialSettlementTransactionIds": [],
    "authorizedTransactionId": null,
    "settlementBatchId": null,
    "shippingAddress": {
        "id": null,
        "customerId": null,
        "firstName": null,
        "lastName": null,
        "company": null,
        "streetAddress": null,
        "extendedAddress": null,
        "locality": null,
        "region": null,
        "postalCode": null,
        "countryCodeAlpha2": null,
        "countryCodeAlpha3": null,
        "countryCodeNumeric": null,
        "countryName": null,
        "createdAt": null,
        "updatedAt": null
    },
    "escrowStatus": {},
    "status": {},
    "statusHistory": [
        {
            "amount": 10,
            "status": {},
            "timestamp": "2019-05-22T20:22:47Z",
            "source": {},
            "user": "mckenna.jones"
        },
        {
            "amount": 10,
            "status": {},
            "timestamp": "2019-05-22T21:00:43Z",
            "source": {},
            "user": "mckenna.jones"
        }
    ],
    "authorizationAdjustments": [],
    "subscriptionId": null,
    "subscriptionDetails": {
        "billingPeriodEndDate": null,
        "billingPeriodStartDate": null
    },
    "taxAmount": null,
    "taxExempt": false,
    "type": {},
    "updatedAt": "2019-05-22T21:00:43Z",
    "customFields": {},
    "serviceFeeAmount": null,
    "disbursementDetails": {
        "settlementAmount": null,
        "settlementCurrencyIsoCode": null,
        "settlementCurrencyExchangeRate": null,
        "fundsHeld": null,
        "success": null,
        "disbursementDate": null
    },
    "applePayDetails": null,
    "androidPayDetails": null,
    "amexExpressCheckoutDetails": null,
    "payPalDetails": null,
    "coinbaseDetails": null,
    "venmoAccountDetails": null,
    "usBankAccountDetails": null,
    "idealPaymentDetails": null,
    "visaCheckoutCardDetails": null,
    "masterpassCardDetails": null,
    "samsungPayCardDetails": null,
    "paymentInstrumentType": {},
    "riskData": null,
    "threeDSecureInfo": null,
    "facilitatedDetails": null,
    "facilitatorDetails": null,
    "discountAmount": null,
    "shippingAmount": null,
    "shipsFromPostalCode": null,
    "networkTransactionId": null,
    "authorizationExpiresAt": null
}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
AdamEssenmachercommented, Jun 4, 2020

This is happening because the Braintree library defined its own Enumeration type instead of using the .NET Enum type. The .NET Enum type implements IConvertible and IFormattable, while the Braintree Enumeration type does not.

If the Braintree.Enumeration type was updated to implement IConvertible and IFormattable, then most serializers would work as expected.

Alternatively, adding a public read-only string property (maybe called Value) backed by the protected Enumeration.Name field would also cause most serializers to work out of the box.

If you were starting from scratch, using the .NET Enum type or making the Braintree Enumeration type implement IConvertible and IFormattable would be ideal IMO.

However, to fix from where we are now, I would recommend adding the public read-only property to the Enumeration type. Depreciating the Enumeration type in favor of the .NET Enum would be a major breaking change for obvious reasons. Implementing IConvertible and IFormattable could be a breaking change in a more subtle way, as you could break some downstream Logstash indexes.

As a work-around, anyone using Json.NET to serialize Braintree objects could use a custom JsonConverter like this:

public class EnumerationConverter : JsonConverter<Enumeration>
{
    public override void WriteJson(JsonWriter writer, Enumeration value, JsonSerializer serializer)
    {
        writer.WriteRawValue($"\"{value}\""); // assuming all Braintree Enumeration strings are safe as a raw json value
    }

    public override Enumeration ReadJson(JsonReader reader, Type objectType, Enumeration existingValue, bool hasExistingValue,
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
0reactions
sestevenscommented, Aug 25, 2020

@mckennajones @AdamEssenmacher We’ve replaced all Braintree.Enumeration subclasses with C# enum types in version 5.0.0, which was just released. This should resolve the serialization issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to exclude empty objects from Jackson ObjectMapper?
I think, a workaround is to write a custom serializer for your type which does nothing if all the fields are null or...
Read more >
Serialization and deserialization in Java
It simply creates an empty object and uses reflection to write the data to the fields. Just like with serialization, private and final ......
Read more >
Use empty string, null or remove empty property in API ...
If it's on a serialization interface, I'd ask myself the following questions about whether or not to use null on a string.
Read more >
JSON serialization: Ignore selective properties or null properties
This article is to explain how to ignore null values or some properties from being serialized to JSON objects for easy transfer of...
Read more >
JSON Serialize - OutSystems 11 Documentation
Errors might occur when the serialized object is empty or only has default values, and these elements are directly accessed, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found