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

52 views Asked by At

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.

2

There are 2 answers

0
MrC aka Shaun Curtis On BEST ANSWER

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

0
jaabh On

You need to read the Content of the HttpResponseMessage in order to get the User. So in order to get the User this would need to be used.

var response = await httpClient.PutAsJsonAsync<User>("api/users", updatedUser);
var user = await response.Content.ReadFromJsonAsync<User>();

//or read as string and then deserialize, whichever is best for you 
//var jsonString = await response.Content.ReadAsStringAsync();
//var user = JsonConvert.DeserializeObject<User>(jsonString);

return user;

The Content of the HttpResponseMessage acts as the body that will contain the User that you are looking for. The entire message is just the http message which contains a status code, header information, etc.