Search code examples
c#asp.net-corehttpentity-framework-core.net-6.0

How to Http PUT json string to API endpoint


I tried several approaches to send an HTTP PUT request to my API but I keep getting:

{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers: { Date: Thu, 27 Jul 2023 02:41:07 GMT Server: Kestrel Transfer-Encoding: chunked Content-Type: text/plain; charset=utf-8 }}

API Server code:

app.MapPut("UpdateFruits", async (string message, IHubContext<ChatHub> context, DatabaseContext dbContext) =>
{
    //message(Param) = { "ID":"2","DisplayName":"Fruit","Leaf":null,"State":"Chopped"}
    try
    {
        // Convert Json to Object... TODO
        var fruit = dbContext.Set<Fruit>().Single(p => p.ID == 1);
        fruit.State = State.Chopped;
        fruit.DisplayName = "test";

        var saved = false;
        while (!saved)
        {
            try
            {
                // Attempt to save changes to the database
                dbContext.SaveChanges();

                saved = true;
            }
            catch (DbUpdateConcurrencyException ex)
            {
                foreach (var entry in ex.Entries)
                {
                    if (entry.Entity is Fruit)
                    {
                        var proposedValues = entry.CurrentValues;
                        var databaseValues = entry.GetDatabaseValues();

                        foreach (var property in proposedValues.Properties)
                        {
                            var proposedValue = proposedValues[property];
                            var databaseValue = databaseValues[property];

                            // TODO: decide which value should be written to database
                            // proposedValues[property] = <value to be saved>;
                        }

                        // Refresh original values to bypass next concurrency check
                        entry.OriginalValues.SetValues(databaseValues);
                    }
                    else
                    {
                        throw new NotSupportedException(
                            "Don't know how to handle concurrency conflicts for "
                            + entry.Metadata.Name);
                    }
                }
            }
        }
        var jsonString = JsonConvert.SerializeObject(fruit);
        await context.Clients.All.SendAsync("ReceiveMessage", "FromServer", jsonString);
    }
    catch (Exception)
    {
    }
    return Results.NoContent();
});

WPF client code:

    private async void sendMessage_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            var client = new HttpClient();
            client.BaseAddress = new Uri("https://localhost:7036");


            var json = System.Text.Json.JsonSerializer.Serialize("{ \"ID\":\"2\",\"DisplayName\":\"Fruit\",\"Leaf\":null,\"State\":\"Chopped\"}");
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var result = await client.PutAsync("/UpdateFruits", content);

        }
        catch (System.Exception ex)
        {
            messages.Items.Add(ex.Message);
        }
    }

Solution

  • You may try as below:
    HttpClient:

    var client = new HttpClient();
            client.BaseAddress = new Uri("https://localhost:xxxx");
            
            var json = "{ \"ID\":\"2\",\"DisplayName\":\"Fruit\",\"Leaf\":null,\"State\":\"Chopped\"}";    
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var result = await client.PutAsync("/UpdateFruits", content);
    

    minimal api:

    app.MapPut("UpdateFruits", (MessageDto message) =>
    {
        .......
        return ....;
    });
    
    public class MessageDto
    {
        public int Id { get; set; }
        public string? DisplayName { get; set; }
        public string? Leaf { get; set; }
    
        public string? State { get; set; }
    }
    

    Result:

    enter image description here

    Documents related:

    Parameter Binding in Minimal API apps

    Make POST, PUT, and DELETE requests with HttpClient