1

I'm buildin a console Web API to communicate with a localhost server, hosting computer games and highscores for them. Every time I run my code, I get this charming error:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] An unhandled exception has occurred while executing the request.

System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'System.Net.Http.HttpContent'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.

This is the method I'm using to post to the database. Note that this method is not in the console application. It is in the ASP.NET Core MvC application opening a web browser and listening for HTTP requests (which can come from the console application).


[HttpPost]
public ActionResult CreateHighscore(HttpContent requestContent)
{
    string jasonHs = requestContent.ReadAsStringAsync().Result;
    HighscoreDto highscoreDto = JsonConvert.DeserializeObject<HighscoreDto>(jasonHs);

    var highscore = new Highscore()
    {
        Player = highscoreDto.Player,
        DayAchieved = highscoreDto.DayAchieved,
        Score = highscoreDto.Score,
        GameId = highscoreDto.GameId
    };

    context.Highscores.Add(highscore);
    context.SaveChanges();
    return NoContent();
}

I'm sending POST requests in a pure C# console application, with information gathered from user input, but the result is exactly the same when using Postman for post requests - the above NotSupportedException.

private static void AddHighscore(Highscore highscore)
{
    var jasonHighscore = JsonConvert.SerializeObject(highscore);
    Uri uri = new Uri($"{httpClient.BaseAddress}highscores");
    HttpContent requestContent = new StringContent(jasonHighscore, Encoding.UTF8, "application/json");

    var response = httpClient.PostAsync(uri, requestContent);
    if (response.IsCompletedSuccessfully)
    {
        OutputManager.ShowMessageToUser("Highscore Created");
    }
    else
    {
        OutputManager.ShowMessageToUser("Something went wrong");
    }
}

I'm new to all this HTTP requests stuff, so if you spot some glaring errors in my code, that would be appreciated. Though, the most important question is, what am I missing, and how can I read from the HttpContent object, to be able to create a Highscore object to send to the database?

It seems to be the string jasonHs... line that is the problem, since the app crashed in exactly the same way, when I commented out the rest of the ActionResult method.

theodorn
  • 149
  • 8
  • What line is throwing the error? Have you inspected `requestContent`? Does it in fact contain the correct JSON? – mxmissile Apr 23 '21 at 17:24
  • I explained it at the end, I think it's ```string jasonHs = requestContent.ReadAsStringAsync().Result;``` since I commented out the other ones. I did inspect requestContent in the console app, and the JSON data was there. For some reason I can't put breakpoints into the ASP.NET solution, they don't dont work or I don't know what I'm doing! – theodorn Apr 23 '21 at 18:10
  • Anyhow, I saw this article recently from Microsoft Docs, https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client - will work through this tutorial soon. It just might contain a solution, but it looks interesting at least. – theodorn Apr 23 '21 at 18:14

1 Answers1

1

Based on your code, we can find that you make a HTTP Post request with a json string data (serialized from a Highscore object) from your console client to Web API backend.

And in your action method, you create an instance of Highscore manually based on received data, so why not make your action accept a Highscore type parameter, like below. Then the model binding system would help bind data to action parameter(s) automatically.

[HttpPost]
public ActionResult CreateHighscore([FromBody]Highscore highscore)
{
    //...
Fei Han
  • 26,415
  • 1
  • 30
  • 41
  • Ended up using HttpResponseMessage, instead of HttpContent in the AddHighscore method above. Worked fine, did not get the exception, I was having trouble with, when using HttpContent. – theodorn May 15 '21 at 22:08