Search code examples
c#asp.net-coreblazordotnet-httpclientapi-design

Cannot implicitly convert type 'System.Net.HttpResponseMessage' to my object


I am new to this and I am facing this problem I am not understanding. I am trying to create a code where I can update the data of a user in my database. Errors shown on the code block below:

using LMSC.Models;
using System.Net.Http;
using System.Net.Http.Json;

namespace LMSC.Blazor.Services
{
    public class UserService : IUserService
    {
        private readonly HttpClient httpClient;
        public UserService(HttpClient httpClient)
        {
            this.httpClient = httpClient;
        }

        public async Task<User> AddUser(User newUser)
        {
            return await httpClient.PostAsJsonAsync<User>("/api/users", newUser); //error here
        }

        public async Task<User> UpdateUser(User updatedUser)
        {
            return await httpClient.PutAsJsonAsync<User>("api/users", updatedUser); //error here
        }
    }
}

This is my UserService file that has the functions needed to do this. I drag the data from the API in my project. It works fine with getting the data but I cannot update an existing user nor create a new one. Here is my UserRepository in my API, that deals with saving information into the database or dragging it out of the DB:

using LMSC.Models;
using Microsoft.EntityFrameworkCore;

namespace LMSC.API.Models
{
    public class UserRepository : IUserRepository
    {
        private readonly AppDbContext appDbContext;

        public UserRepository(AppDbContext appDbContext)
        {
            this.appDbContext = appDbContext;
        }

        public async Task<User> UpdateUser(User user)
        {
            var result = await appDbContext.Users.FirstOrDefaultAsync(u => u.UserID == user.UserID);

            if (result == null)
            {
                result.FirstName = user.FirstName;
                result.LastName = user.LastName;
                result.Email = user.Email;
                result.RoleID = user.RoleID;
                result.DateOfBirth = user.DateOfBirth;
                result.Gender = user.Gender;
                result.PhotoPath = user.PhotoPath;

                await appDbContext.SaveChangesAsync();

                return result;
            }

            return null;
        }

        public async Task<User> AddUser(User user)
        {
            var result = await appDbContext.Users.AddAsync(user);
            await appDbContext.SaveChangesAsync();
            return result.Entity;
        }
    }
}

Here is the UserController file that checks for possible errors with try-catch method:

using LMSC.API.Models;
using LMSC.Models;
using Microsoft.AspNetCore.Mvc;

namespace LMSC.API.Controllers
{
    [Route("/api/[controller]")]
    [ApiController]
    public class UsersController : ControllerBase
    {
        private readonly IUserRepository userRepository;
        public UsersController(IUserRepository userRepository)
        {
            this.userRepository = userRepository;
        }


        [HttpPost]
        public async Task<ActionResult<User>> AddUser(User user)
        {
            try
            {
                if (user == null)
                {
                    return BadRequest();
                }

                var createdUser = await userRepository.AddUser(user);

                return CreatedAtAction(nameof(GetUser), new { id = createdUser.UserID }, createdUser);
            }
            catch (Exception)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, "Error retrieving data from the Database");
            }
        }

        [HttpPut]
        public async Task<ActionResult<User>> UpdateUser(User user)
        {
            try
            {
                var userToUpdate = await userRepository.GetUser(user.UserID);

                if (userToUpdate == null)
                {
                    return NotFound($"User with ID = {user.UserID} not found");
                }

                return await userRepository.UpdateUser(user);
            }
            catch (Exception)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, "Error retrieving data from the Database");
            }
        }
    }
}

On the UserService file it constantly shows the error message "CS0029 - Cannot implicitly convert type 'System.Net.HttpResponseMessage' to 'LMSC.Models.User'". I tried looking online for possible explanations and looking back on my tutorials in case I missed something but I havent found anything.

I am very new to this so it is most likely something obvious but if you would be kind enough to give me an idea on what I'm missing it would mean a lot.


Solution

  • Your controller is returning a HttpResponseMessage, not a User.

    You need read the returned HttpResponseMessage state and decode the contents.

    public async Task<User> AddUser(User newUser)
    {
         var response = await httpClient.PostAsJsonAsync<User>("/api/users", newUser);
        if (response.IsSuccessStatusCode)
        {
           var result = await response.Content.ReadFromJsonAsync<User>();
           //.....
           return result;
        }
           //..... Handle bad response
    
    }
    

    If you aren't already doing so read this on how to use the IHttpClientFactory - https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory