Javascript passing null to an ExpandoObject field in C# Controller parameter

194 views Asked by At

My Javascript Code

$('[step="4"]').click(function () {
//shortened for brevety
var _model = new Object();
_model.ItemDesc.value = 'Descript';
//^ throws an error but gets fixed if removing the .value
_model.ItemQty.num = 1;
_model.ItemQty.unit = 'pcs'

    $.ajax({
        type: "POST",
        url: 'CreateItemCallAsync',
        data: _model,
        success: function (msg) {
            status = JSON.stringify(msg);
            alert('Item created successfully!');
            location.reload();
        },
        error: function (msg) {
            status = JSON.stringify(msg);
            alert('Failed to create item.');
            location.reload();
        }
    });
});

C# Controller Code

[HttpPost]
public async Task<JsonResult> CreateItemCallAsync(CreateItemModel item)
{
   //breakpoint here 
   var test = item.ItemDesc;
   var qty = item.ItemQty.num; //getting nulls here
   var unit = item.ItemQty.unit; //getting nulls here
}

C# CreateItemModel

public class CreateItemModel
{
   public string ItemName { get; set; }
   public string ItemDesc { get; set; }
   public ExpandoObject ItemQty { get; set; }
}

JavaScript Object

[
  {
     ItemName : 'Item1',
     ItemDesc : 'Descript'
     ItemQty : { num : 5 , unit: 'pcs'}
  },
  {
     ItemName : 'Item2',
     ItemDesc : 'Descript'
     ItemQty : { num : 1 , unit: 'box'}
  }
]

From the code above. I have a JavaScript object passed to my C# controller with a CreateItemModel parameter that has a field of ItemQty as an ExpandoObject. However, after passing to my C# controller. the ItemQty.num and ItemQty.unit are null.

With further investigating, before passing the JavaScript object to C# controller. the Objects are successfully populated.

I need ItemQty as an ExpandoObject because the fields/properites under ItemQty is always changing/dynamic

Questions:

  1. (Bit of off topic) why _model.ItemDesc.value = 'Descript' errors? On the other hand _model.ItemDesc = 'Descript' runs without error.
  2. Why am I getting nulls in ItemQty properties?
1

There are 1 answers

0
D-Shih On

(Bit of off topic) why _model.ItemDesc.value = 'Descript' errors? On the other hand _model.ItemDesc = 'Descript' runs without error.

Because there isn't a property ItemDesc,ItemQty,ItemQty in original javascript Object.

You can try to create an anonymous JSON object for your javascript code.

var _model = {     
    ItemDesc: {
        value : "Descript"
    }, 
    ItemQty :{
        num : 1,
        unit :'pcs'
    }
};

instead of

var _model = new Object();
_model.ItemDesc.value = 'Descript';
_model.ItemQty.num = 1;
_model.ItemQty.unit = 'pcs'

your c# model might look like because your currently ItemDesc is an object instead of a string value.

Why am I getting nulls in ItemQty properties?

Because default ModelBindiner can't find ExpandoObject with your JSON key ItemQty object.

public class ItemDesc
{
    public string value { get; set; }
}

public class ItemQty
{
    public int num { get; set; }
    public string unit { get; set; }
}

public class CreateItemModel
{
    public ItemDesc ItemDescContext { get; set; }
    public ItemQty ItemQtyContext { get; set; }
}