Search code examples
c#asp.net-coreazure-service-fabric

FromBody in ASP.NET Core API returns null


I have created a stateful ASP.NET Core service with 10 partitions in Azure Service Fabric with API as the project template and ASP.NET Core 3.0. I am trying to send an object of class SupplierMaterialMaintenance through Postman in JSON to my stateful service as shown in the figure below :-

enter image description here

Here is the JSON file that I am trying to send.

{
    "SupplierMaterialAssociationGuid": "6ef61a2b-963e-4993-ac73-5e07f707c2e2",
    "MinimumOrderQuantity": 1,
    "UnitOfMeasurementGuid": "771d4f76-9321-442f-b2c2-9f75b1a7cda8",
    "ConversionFactor": 2,
    "POPrice": 123.00000,
    "OrderLeadTime": 10,
    "IssueMinimumLot": 0,
    "ContainerQuantity": 10,
    "InnerContainerQuantity": 1,
    "NoOfInnerContainers": 10,
    "SupplierMaterialNumber": null,
    "SupplierMaterialName": null,
    "POPriceExcludingMetal": 123.00000,
    "InitialVolumeQuantity": 1,
    "ReplacementMaterialNumber": "",
    "MetalWeight": 0.0,
    "MetalRate": 0.0,
    "StandardBoxLength": 0.0,
    "StandardBoxHeight": 0.0,
    "StandardBoxWidth": 0.0,
    "StandardPackFactor": 10,
    "FullBoxWeight": 0.0,
    "TariffCodeGuid": "00000000-0000-0000-0000-000000000000",
    "CountryRegionsAssociationGuid": "00000000-0000-0000-0000-000000000000",
    "ExpiryDate": "0001-01-01T00:00:00",
    "IsActive": true,
    "MatSuppMainSupplier": false,
    "EUPreferentialOriginStatusCode": null,
    "Id": "ead6cbc7-baff-430d-b83b-4914a916aabd",
    "Name": null,
    "CreatedDate": "2019-07-09T01:53:49.659194",
    "ModifiedDate": "2019-07-09T01:53:49.659194",
    "CreatedBy": "13beef85-3939-4998-b912-22d8df2cd966",
    "ModifiedBy": "13beef85-3939-4998-b912-22d8df2cd966",
    "IsRowChecked": false,
    "Version": null,
    "CrudOperationType": 0,
    "Error": null
}

And here is my controller :-

using Microsoft.AspNetCore.Mvc;
using Microsoft.ServiceFabric.Data;
using Microsoft.ServiceFabric.Data.Collections;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MyStatefulService.Models;
using System.Net.Http;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

namespace MyStatefulService.Controllers
{
    [Produces("application/json")]
    [Route("api/[controller]")]
    [ApiController]
    public class DefaultController : Controller
    {
        private readonly IReliableStateManager reliableStateManager;

        public DefaultController(IReliableStateManager reliableStateManager)
        {
            this.reliableStateManager = reliableStateManager;
        }

        // GET api/Default
        [HttpGet]
        public async Task<IActionResult> Get()
        {
            CancellationToken ct = new CancellationToken();

            IReliableDictionary<Guid, SupplierMaterialMaintenance> myDictionary = await this.reliableStateManager.GetOrAddAsync<IReliableDictionary<Guid, SupplierMaterialMaintenance>>("dictionary");

            using (ITransaction tx = this.reliableStateManager.CreateTransaction())
            {
                Microsoft.ServiceFabric.Data.IAsyncEnumerable<KeyValuePair<Guid, SupplierMaterialMaintenance>> list = await myDictionary.CreateEnumerableAsync(tx);

                Microsoft.ServiceFabric.Data.IAsyncEnumerator<KeyValuePair<Guid, SupplierMaterialMaintenance>> enumerator = list.GetAsyncEnumerator();

                List<KeyValuePair<Guid, SupplierMaterialMaintenance>> result = new List<KeyValuePair<Guid, SupplierMaterialMaintenance>>();

                while (await enumerator.MoveNextAsync(ct))
                {
                    result.Add(enumerator.Current);
                }

                return this.Json(result);
            }
        }

        // PUT api/Default/name
        [HttpPost]
        public async Task<IActionResult> Post([FromBody] SupplierMaterialMaintenance obj)
        {
            SupplierMaterialMaintenance obj1 = new SupplierMaterialMaintenance();
            if (ModelState.IsValid)
            {
                obj1 = obj;
            }
            IReliableDictionary<Guid, SupplierMaterialMaintenance> myDictionary = await this.reliableStateManager.GetOrAddAsync<IReliableDictionary<Guid, SupplierMaterialMaintenance>>("dictionary");

            using (ITransaction tx = this.reliableStateManager.CreateTransaction())
            {
                await myDictionary.AddOrUpdateAsync(tx, obj1.SupplierMaterialAssociationGuid, obj1, (key, oldvalue) => obj1);
                await tx.CommitAsync();
            }

            return new OkResult();
        }
    }
}

And here is the class SupplierMaterialMaintenance :-

public class SupplierMaterialMaintenance : IComparable<SupplierMaterialMaintenance>, IEquatable<SupplierMaterialMaintenance>
    {

        public Guid SupplierMaterialAssociationGuid;
        public int MinimumOrderQuantity;
        public Guid UnitOfMeasurementGuid;
        public int ConversionFactor;
        public decimal POPrice;
        public int OrderLeadTime;
        public int IssueMinimumLot;
        public int ContainerQuantity;
        public int InnerContainerQuantity;
        public int NoOfInnerContainers;
        public string SupplierMaterialNumber;
        public string SupplierMaterialName;
        public decimal POPriceExcludingMetal;
        public int InitialVolumeQuantity;
        public string ReplacementMaterialNumber;
        public decimal MetalWeight;
        public decimal MetalRate;
        public decimal StandardBoxLength;
        public decimal StandardBoxHeight;
        public decimal StandardBoxWidth;
        public int StandardPackFactor;
        public decimal FullBoxWeight;
        public Guid TariffCodeGuid;
        public Guid CountryRegionsAssociationGuid;
        public DateTime ExpiryDate;
        public bool IsActive;
        public bool MatSuppMainSupplier;
        public string EUPreferentialOriginStatusCode;
        public Guid Id;
        public string Name;
        public string CreatedDate;
        public string ModifiedDate;
        public Guid CreatedBy;
        public Guid ModifiedBy;
        public bool IsRowChecked;
        public string Version;
        public int CrudOperationType;
        public string Error;

        public int CompareTo(SupplierMaterialMaintenance obj)
        {
            if (obj != null)
            {
                SupplierMaterialMaintenance otherObj = obj as SupplierMaterialMaintenance;

                if (otherObj != null)
                {
                    return otherObj.SupplierMaterialAssociationGuid.CompareTo(this.SupplierMaterialAssociationGuid);
                }
                else
                {
                    throw new ArgumentException("Object is not a SupplierMaterialMaintenance");
                }
            }
            return 1;
        }

        public bool Equals(SupplierMaterialMaintenance obj)
        {
            if (obj == null) return false;

            return obj.SupplierMaterialAssociationGuid.Equals(this.SupplierMaterialAssociationGuid);
        }
    }

Whenever I hit the send button in Postman, I am always getting an object of class X initialised with default values as shown below :-

enter image description here

I have searched numerous questions on StackOverflow but to no success. What am I doing wrong here ?


Solution

  • You need to change all of your fields in the SupplierMaterialMaintenance class to the properties with getter and setter

    public class SupplierMaterialMaintenance : IComparable<SupplierMaterialMaintenance>, IEquatable<SupplierMaterialMaintenance>
    {
        public Guid SupplierMaterialAssociationGuid { get; set; }
        public int MinimumOrderQuantity { get; set; }
        public Guid UnitOfMeasurementGuid { get; set; }
        public int ConversionFactor { get; set; }
        //goes like this...
    

    You can take a look at Microsoft Documentation about Model Binding in .net-core