locked
Receiving JSON Request and send JSON Response RRS feed

  • Question

  • User-1917797656 posted

    Hi,

    I just start a new project to learn web api and i have a problem to receive JSON Request via (POSTMAN) and show a JSON Response.

    Here's my two classes : 

    using System.ComponentModel.DataAnnotations;
    
    namespace BookService.Models
    {
        public class Book
        {
            public int Id { get; set; }
            [Required]
            public string Title { get; set; }
            public int Year { get; set; }
            public decimal Price { get; set; }
            public string Genre { get; set; }
    
            // Foreign Key
            public int AuthorId { get; set; }
            // Navigation property
            public Author Author { get; set; }
        }
    }
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace BookService.Models
    {
        public class Author
        {
            public int Id { get; set; }
            [Required]
            public string Name { get; set; }
        }
    }

    And my controllers : 

    /*This one give me a json response but i'm sendig the id as a number without json format*/
    [HttpPost]
            [Route("api/BodyTypes/JsonStringBody")]
            public async Task<IHttpActionResult> JsonStringBody([FromBody] int id)
            {
                try
                {
                    var book = await db.Books.Include(b => b.Author).Select(b =>
                        new BookDetailDTO()
                        {
                            Id = b.Id,
                            Title = b.Title,
                            Year = b.Year,
                            Price = b.Price,
                            AuthorName = b.Author.Name,
                            Genre = b.Genre
                        }).SingleOrDefaultAsync(b => b.Id == id);
                    return Ok(book);
                }
                catch (Exception ex)
                {
                    return BadRequest();
                }
    
            }
    /*And i have problem at this part*/
            [HttpPost]
            [Route("api/BodyTypes/JsonBody")]
            public Book JsonBodyAsync([FromBody] Book book)
            {
                try
                {
                    var pp = db.Books.Include(b => book.Author.Id).Select(b =>
                        new Book()
                        {
                            Id = b.Id,
                            Title = b.Title,
                            Year = b.Year,
                            Price = b.Price,
                            Author = b.Author,
                            Genre = b.Genre
                        }).SingleOrDefaultAsync(b => b.Id == book.Id);
                    var response = (JArray)JsonConvert.DeserializeObject(pp.ToString());
                    var JsonData = JsonConvert.SerializeObject(response);
                    return JsonData;
                }
                catch (Exception ex)
                {
                    return null;
                }
                
            }

    Would you help me ?

    Monday, April 8, 2019 10:17 AM

Answers

  • User-1917797656 posted

    Okay thanks, I managed to do it with the following code : 

    [HttpPost, Route("api/BodyTypes/JsonFromBody")]
            public IHttpActionResult JsonFromBody([FromBody] Book book)
            {
                try
                {
                    var papa = db.Books.Include(b => b.Author).Select(b =>
                        new BookDetailDTO()
                        {
                            Id = b.Id,
                            Title = b.Title,
                            Year = b.Year,
                            Price = b.Price,
                            AuthorName = b.Author.Name,
                            Genre = b.Genre
                        }).SingleOrDefaultAsync(b => b.Id == book.Id);
                    return Json(papa);
                }
                catch (Exception ex)
                {
                    return Json("Erreur de chargement");
                }
                //return Json(book);
            }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, April 8, 2019 2:36 PM

All replies

  • User753101303 posted

    Hi,

    When posting code, always be explicit about the problem you have. It seems you want basically use just the same code except that the id is posted as part of an object ??? So it could be :

     [HttpPost]
            [Route("api/BodyTypes/JsonBody")]
            public Book JsonBodyAsync([FromBody] Book book)
            {
                try
                {
                    var pp = db.Books.Include(b => book.Author.Id).Select(b =>
                        new Book()
                        {
                            Id = b.Id,
                            Title = b.Title,
                            Year = b.Year,
                            Price = b.Price,
                            Author = b.Author,
                            Genre = b.Genre
                        }).SingleOrDefaultAsync(b => b.Id == book.Id);
                    return Ok(pp);
                }
                catch (Exception ex)
                {
                    return null;
                }
                
            }

    Serialiazing/deserializing is handled for you by ASP.NET so you should rarely need to do that explicitely in code. Here you tried to deserialize from pp.ToString() which doesn't make sense (it returns a type name) and anyway you just try to serialiaze that again right away.

    Not directly related but the exception handling could be confusing (it will return null as soon as your code fails regardless of the reason which doesn't really help in finding programming errors).

    Monday, April 8, 2019 10:47 AM
  • User-1917797656 posted

    I have tried that before, but it gave me an error : 

    Monday, April 8, 2019 10:55 AM
  • User753101303 posted

    Ah for some reason you changed also the signature. What if you try:

     public async Task<Book> JsonStringBody([FromBody] int id)
    
    Monday, April 8, 2019 11:02 AM
  • User-1917797656 posted

    But with that i cannot send a json request

    Monday, April 8, 2019 11:06 AM
  • User753101303 posted

    My bad I meant it seems you want (though I'm not sure to get which benefit you get by having both) :

     public async Task<Book> JsonBodyAsync([FromBody] Book book)
    Monday, April 8, 2019 11:11 AM
  • User-1917797656 posted

    I'm just training, all of this is new for me..

    Although your answer may have a problem somewhere 

    Error 1 : 

    Error 2 : 

    Monday, April 8, 2019 1:38 PM
  • User-474980206 posted

    You should show the json you are posting via postman.

    Also you can not return Ok, if you define the action as returning a Book. You must return a Book.
    Monday, April 8, 2019 2:14 PM
  • User753101303 posted

    Ah... just use return pp; as you want to return a Book (the other one returns an IHttpActiohResult).

    Generally speaking this message happens because your function is supposed to return a given type but actually returns another type which can't be implicitely converted to the one you want. Is this change intended as well or do is your intent to change nothing at all expect how the id is passed ?

    See https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results which explain what a web api method can return to clients (here you used first #3 but then #4 for your other version)...

    Monday, April 8, 2019 2:23 PM
  • User-1917797656 posted

    Okay thanks, I managed to do it with the following code : 

    [HttpPost, Route("api/BodyTypes/JsonFromBody")]
            public IHttpActionResult JsonFromBody([FromBody] Book book)
            {
                try
                {
                    var papa = db.Books.Include(b => b.Author).Select(b =>
                        new BookDetailDTO()
                        {
                            Id = b.Id,
                            Title = b.Title,
                            Year = b.Year,
                            Price = b.Price,
                            AuthorName = b.Author.Name,
                            Genre = b.Genre
                        }).SingleOrDefaultAsync(b => b.Id == book.Id);
                    return Json(papa);
                }
                catch (Exception ex)
                {
                    return Json("Erreur de chargement");
                }
                //return Json(book);
            }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, April 8, 2019 2:36 PM