Just Add Water
Just Add Water

Reputation: 25

c# convert nested sub classes to json

I am trying to (serialise?) a class in to JSON and am getting a null reference exception - please can you help me understand why and possible fix this?

I wrote a class which contains several nested classes (the JSON structure was provided by the UK carrier DPD).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace DPDJSONLibrary
{
    public class DPD_JSON
    {
    // insert shipment request
        /// <summary>
        /// Root Object. Insert Shipment Request
        /// </summary>
        public class IS
        {
            public string job_id { get; set; }
            public bool collectionOnDelivery { get; set; }
            public IS_Invoice invoice { get; set; }
            public string collectionDate { get; set; }
            public bool consolidate { get; set; }
            public IS_Consignment consignment { get; set; }
        }
        public class IS_Address
        {
            public string addressId { get; set; }
            public string countryCode { get; set; }
            public string countryName { get; set; }
            public string county { get; set; }
            public string locality { get; set; }
            public string organisation { get; set; }
            public string postcode { get; set; }
            public string street { get; set; }
            public string town { get; set; }
        }
        public class IS_ContactDetails
        {
            public string contactName { get; set; }
            public string telephone { get; set; }
        }
        public class IS_PickupLocation
        {
            public IS_Address address { get; set; }
            public bool allowRemotePickup { get; set; }
            public string pickupLocationCode { get; set; }
        }
        public class IS_NotificationDetails
        {
            public string email { get; set; }
            public string mobile { get; set; }
        }
        public class IS_ParcelProduct
        {
            public string countryOfOrigin { get; set; }
            public Int32 numberOfItems { get; set; }
            public string productCode { get; set; }
            public string productFabricContent { get; set; }
            public string productHarmonisedCode { get; set; }
            public string productItemsDescription { get; set; }
            public string productTypeDescription { get; set; }
            public decimal unitValue { get; set; }
            public decimal unitWeight { get; set; }
        }

        public class IS_InvoiceItem
        {
            public string countryOfOrigin { get; set; }
            public string itemCode { get; set; }
            public string itemDescription { get; set; }
            public int numberOfItems { get; set; }
            public decimal unitValue { get; set; }
        }

        public class IS_InvoiceBillingDetails
        {
            public IS_Address address { get; set; }
            public IS_ContactDetails contactDetails { get; set; }
            public string vatNumber { get; set; }
        }

        public class IS_Invoice
        {
            public string countryOfOrigin { get; set; }
            public IS_InvoiceBillingDetails invoiceBillingDetails { get; set; }
            public string invoiceCustomsNumber { get; set; }
            public string invoiceExportReason { get; set; }
            public bool invoiceIsDeclared { get; set; }
            public IS_InvoiceItem invoiceItem { get; set; }
            public string invoiceTermsOfDelivery { get; set; }
            public int invoiceType { get; set; }
            public int totalItems { get; set; }
            public decimal totalValue { get; set; }
            public decimal totalWeight { get; set; }
        }

        public class IS_DeliveryDetails
        {
            public IS_Address address { get; set; }
            public IS_ContactDetails contactDetails { get; set; }
            public IS_NotificationDetails notificationDetails { get; set; }
            public IS_PickupLocation deliveryDetails { get; set; }
        }

        public class IS_CollectionDetails
        {
            public IS_Address address { get; set; }
            public IS_ContactDetails contactDetails { get; set; }
        }

        public class IS_Parcels
        {
            public bool isVoided { get; set; }
            public string labelNumber { get; set; }
            public int packageNumber { get; set; }
            public string parcelNumber { get; set; }
            public IS_ParcelProduct parcelProduct { get; set; }
            public string parcelnetBarcode { get; set; }
            public string parcelnetData { get; set; }
            public string parcelnetLabelNumber { get; set; }
        }

        public class IS_Consignment
        {
            public IS_CollectionDetails collectionDetails { get; set; }
            public string consignmentNumber { get; set; }
            public string consignmentRef { get; set; }
            public decimal? customsValue { get; set; }
            public IS_DeliveryDetails deliveryDetails { get; set; }
            public string deliveryInstructions { get; set; }
            public bool liability { get; set; }
            public decimal liabilityValue { get; set; }
            public string networkCode { get; set; }
            public int numberOfParcels { get; set; }
            public IS_Parcels parcel { get; set; }
            public string parceldescription { get; set; }
            public string shippingRef1 { get; set; }
            public string shippingRef2 { get; set; }
            public string shippingRef3 { get; set; }
            public decimal totalWeight { get; set; }
        }
    }
}

I have another class containing public variables which I assign values to from code, and a method/function to instantiate my JSON class and pull in the values from the public variables.

I am getting a null reference exception on the line:

NewShipmentObject.consignment.consignmentNumber = null;

The error reads:

error System.NullReferenceException: Object reference not set to an instance of an object

The method I cam calling and getting the error in is below:

using System;
using System.Text;
using System.Net;
// include
using System.IO;
using System.Web.UI.WebControls;
using DPDJSONLibrary;
using System.Web;
using Newtonsoft.Json;

namespace DPDAPILibrary
{
    public class DPD_API
    {

        #region public class variables
        public string BusinessUnit;
        public string DeliveryDirection;
        public string NumberOfParcels; 
        public string ShipmentType;
        public string TotalWeight;
        public string CollectionDate;
        public string ColName;
        public string ColPhone;
        public string ColOrganisation;
        public string ColCountryCode;
        public string ColPostCode;
        public string ColStreet;
        public string ColLocality;
        public string ColTown;
        public string ColCounty;
        public string DelName;
        public string DelPhone;
        public string DelOrganisation;
        public string DelCountryCode;
        public string DelPostcode;
        public string DelStreet;
        public string DelLocality;
        public string DelTown;
        public string DelCounty;
        public string DelNotificationEmail;
        public string DelNotificationMobile;
        public string NetworkCode;
        public string ShippingRef1;
        public string ShippingRef2;
        public string ShippingRef3;
        public string CustomsValue;
        public string DeliveryInstructions;
        public string ParcelDescription;
        public string LiabilityValue;
        public string Liability;
        #endregion


        public Boolean insertShipment(out string JSONData)
        {
            try
            {
                DPD_JSON.IS NewShipmentObject = new DPD_JSON.IS();

                NewShipmentObject.job_id = null;
                NewShipmentObject.collectionOnDelivery = false;
                NewShipmentObject.invoice = null;
                NewShipmentObject.collectionDate = CollectionDate;
                NewShipmentObject.consolidate = false;
                NewShipmentObject.consignment.consignmentNumber = null;
                NewShipmentObject.consignment.consignmentRef = null;
                NewShipmentObject.consignment.parcel = null;

                NewShipmentObject.consignment.collectionDetails.contactDetails.contactName = ColName;
                NewShipmentObject.consignment.collectionDetails.contactDetails.telephone = ColPhone;
                NewShipmentObject.consignment.collectionDetails.address.organisation = ColOrganisation;
                NewShipmentObject.consignment.collectionDetails.address.countryCode = ColCountryCode;
                NewShipmentObject.consignment.collectionDetails.address.postcode = ColPostCode;
                NewShipmentObject.consignment.collectionDetails.address.street = ColStreet;
                NewShipmentObject.consignment.collectionDetails.address.locality = ColLocality;
                NewShipmentObject.consignment.collectionDetails.address.town = ColTown;
                NewShipmentObject.consignment.collectionDetails.address.county = ColCounty;

                NewShipmentObject.consignment.deliveryDetails.contactDetails.contactName = ColName;
                NewShipmentObject.consignment.deliveryDetails.contactDetails.telephone = DelPhone;
                NewShipmentObject.consignment.deliveryDetails.address.organisation = DelOrganisation;
                NewShipmentObject.consignment.deliveryDetails.address.countryCode = DelCountryCode;
                NewShipmentObject.consignment.deliveryDetails.address.postcode = DelPostcode;
                NewShipmentObject.consignment.deliveryDetails.address.street = DelStreet;
                NewShipmentObject.consignment.deliveryDetails.address.locality = DelLocality;
                NewShipmentObject.consignment.deliveryDetails.address.town = DelTown;
                NewShipmentObject.consignment.deliveryDetails.address.county = DelCounty;

                NewShipmentObject.consignment.deliveryDetails.notificationDetails.email = DelNotificationEmail;
                NewShipmentObject.consignment.deliveryDetails.notificationDetails.mobile = DelNotificationMobile;

                // default output value
                JSONData = "";

                JSONData = Convert.ToString(JsonConvert.SerializeObject(NewShipmentObject));

            }
            catch (Exception ex)
            {
                JSONData = Convert.ToString(ex);
                return false;
            }
        }
    }
}

Upvotes: 0

Views: 254

Answers (1)

StuartLC
StuartLC

Reputation: 107247

You'll need to initialize all objects (including child entities) before you can use them*, as they will otherwise adopt their default values (which will be null for objects). i.e. replace

NewShipmentObject.consignment.consignmentNumber = null;

with:

NewShipmentObject.consignment = new IS_Consignment();
NewShipmentObject.consignment.consignmentNumber = null;

You can save yourself a lot of typing - instead of line-by-line setting of each field, you can do so using Object Initializer Syntax:

var NewShipmentObject = new DPD_JSON.IS
{
    job_id = null,
    collectionOnDelivery = false,
    consignment = new IS_Consignment
    {
        consignmentNumber = null,
        ... more consignment settings here
    }
    ... etc.

It should be noted that you don't need to explicitly set uninitialized variables to their default value, i.e. both

job_id = null,
collectionOnDelivery = false

are redundant, as these should be the default values in any event.

* (unless this initialization is done automatically in the constructor)

Upvotes: 1

Related Questions