Search code examples
c#asp.net-core-webapisingle-page-applicationwebapiasp.net-mvc-viewmodel

posting object with arrays in Asp.net core Web Api


I have SPA with react as front-end and Asp.net core web api as back-end. I want to post the order and orderDetails to WebApi and tried to handle it using OrderViewModel in controller.

edit: i have found out an error and resolved it.that in orderDetails.cs Model Qty should be changed to Amount and tried but the same error occured screenshot also attached.

the json request payload is as follows:

{
Email: "[email protected]"
address: "1km mianwal road kuthiala sheikhan"
city: "mandi bahauddin"
customerName: "fiaz ahmed"
discount: 0
mobile: "03466469074"
orderDetails: [{productId: 1, productName: "shalwarqamees", productCode: "101", discount: 200, amount: 1,…},…]
qty: 3
total: 1800
whatsapp: "03466469074"}

at the back-end the order.cs model is as:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace WebApi.Models
{
   
    public partial class Order
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Key]
        public int OrderId { get; set; }
        public int Qty { get; set; }
        [Required]
        [StringLength(160)]
        public string CustomerName { get; set; }
        [Required]
        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }
        [Required]
        [DataType(DataType.PhoneNumber)]
        public string Mobile { get; set; }

        [DataType(DataType.PhoneNumber)]
        public string Whatsapp { get; set; }
        [Required]
        [StringLength(100)]
        public string City { get; set; }
      [Required]
        [DataType(DataType.MultilineText)]
        public string Address { get; set; }
        public int StoreId { get; set; }
        public long ShopId { get; set; }
        [StringLength(70)]
        public string Status { get; set; }

        public decimal Total { get; set; }
       
        public decimal Discount { get; set; }
        [DataType(DataType.Date)]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
        public System.DateTime UpdatedOn { get; set; }

    }
}

here is the oderDetails.cs model:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace WebApi.Models
{
    public class OrderDetail
    {
        public int OrderDetailId { get; set; }
      
        public int ProductId { get; set; }
        public int Qty { get; set; }
        public string ProductCode { get; set; }
        public string ProductName { get; set; }
        public int StoreId { get; set; }    
        public string Unit { get; set; }
        public decimal Price { get; set; }
        public decimal Discount { get; set; }

        public string Currency { get; set; }
    }
}

the OrderViewModel.cs in Models is as :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace WebApi.Models
{
    public class OrderViewModel
    {
        public Order Order { get; set; }
        public List<OrderDetail> OrderDetails { get; set; }
    }
}

the post action method in orderscontroller is as follows:

 [HttpPost]
        public async Task<ActionResult<OrderViewModel>> PostOrder(OrderViewModel order)
        {

           
         var ord = order.Order;  //save order in ord variable from orderviewmodel
            ord.UpdatedOn = DateTime.UtcNow;
            _context.Order.Add(ord); // here is null reference error
            var od = order.OrderDetails.ToList(); // get all orderdetails array of objects from orderviewmodel
            foreach (var d in od)     
            {
                _context.OrderDetails.Add(d);  //enter all products  details  in orderdetails table
            }
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetOrder", new { id = ord.OrderId }, order);
        }

the error is as follows: System.NullReferenceException: Object reference not set to an instance of an object. screenshot is here: screenshot of error in controller The app is an online store and I want to post the order and details of products to back-end to store in the database. thanks in advance for workaround and help.


Solution

  • Your JSON does not match your view model. So my guess is because you don't specify the order object in your JSON. In your view model, Order will be null and you get a null exception at this line ord.UpdatedOn = DateTime.UtcNow;

    Try something like this

    {
      "order": {
        "Email": "[email protected]",
        "address": "1km mianwal road kuthiala sheikhan",
        "city": "mandi bahauddin",
        "customerName": "fiaz ahmed",
        "discount": 0,
        "mobile": "********",
        "qty": 3,
        "total": 1800,
        "whatsapp": "********"
      },
      "orderDetails": [
        {
          "productId": 1,
          "productName": "shalwarqamees",
          "productCode": "101",
          "discount": 200,
          "amount": 1,
          "…"
        },
        {
          "productId": 2,
          "productName": "asdqwesdasdasd",
          "productCode": "201",
          "discount": 300,
          "amount": 2,
          "…"
        }
      ]
    }
    

    By the way, it is not a good practice to expose your dbContext's models to your frontend directly. Consider using DTO or POCO in the middle.