Search code examples
c#asp.netmauiasp.net-apicontroller

How to transfer JSON to the POST api in asp.net and convert it into a data model


I have very little experience with the API. I am trying to transfer data about viewing a product record from my mobile app .NET MAUI to the server ASP.NET using an HttpPost request. I am trying to transfer data from the mobile client in the form of JSON using String Content, as suggested in the documentation. But I still couldn't find information on how to get this JSON and convert it to an instance of the View class.

My API HttpPost code:

[Route("api/[controller]")]
[ApiController]
public class ViewController : ControllerBase
{

    // POST api/<ViewController>
    [HttpPost]
    public async void Post(int id, DateOnly date, TimeOnly time)
    {
        using (VapeshopContext db = new VapeshopContext())
        {
            View view = new View
            {
                Date = date,
                Time = time,
                ProductId = id
            };
            db.Views.Add(view);
            await db.SaveChangesAsync();
        }
    }    
}

My POST request code:

 private async void toInfoPage(object obj)
 {
     if (obj != null)
     {         
         var p = obj as Product;
         using StringContent jsonContent = new(
             JsonSerializer.Serialize(new
             {
                 Date = DateOnly.FromDateTime(DateTime.Now),
                 Time = TimeOnly.FromDateTime(DateTime.Now),
                 ProductId = p.Id
             }),
             Encoding.UTF8, "application/json");
         await httpClient.PostAsJsonAsync("http://10.0.2.2:5125/api/View",jsonContent);

        var newPage = new ProductInfo(obj as Product);
        await Navigation.PushAsync(newPage);
     }
 }

When passing a pre-prepared model to the API, it is filled with zero values values of the model parameters


Solution

  • You can convert your POST body into a Model:

    public class MyObjectModel
    {
        public int ProductId {get;set;}
        public DateOnly Date {get;set;}
        public TimeOnly Time {get;set;}
    }
    

    And change your toInfoPage method to:

     private async void toInfoPage(object obj)
     {
         if (obj != null)
         {         
             var p = obj as Product; 
             using StringContent jsonContent = new(
                 JsonSerializer.Serialize(new MyObjectModel
                 {
                     Date = DateOnly.FromDateTime(DateTime.Now),
                     Time = TimeOnly.FromDateTime(DateTime.Now),
                     ProductId = Convert.ToInt32(p.Id)
                 }),
                 Encoding.UTF8, "application/json");
                 
             await httpClient.PostAsync("http://10.0.2.2:5125/api/View",jsonContent);
    
            var newPage = new ProductInfo(obj as Product);
            await Navigation.PushAsync(newPage);
         }
     }
    

    And finally retrieve the MyObjectModel at your endpoint using FromBody attribute:

    [Route("api/[controller]")]
    [ApiController]
    public class ViewController : ControllerBase
    {
    
        // POST api/<ViewController>
        [HttpPost]
        public async void Post([FromBody] MyObjectModel model)
        {
            using (VapeshopContext db = new VapeshopContext())
            {
                View view = new View
                {
                    Date = model.Date,
                    Time = model.Time,
                    ProductId = model.ProductId
                };
                db.Views.Add(view);
                await db.SaveChangesAsync();
            }
        }    
    }