DEV Community

Masui Masanori
Masui Masanori

Posted on

[C#] Try sending data by HttpClient

Intro

This time, I will try sending data from a console application.

An ASP.NET Core applicaion for receiving the data

To receive the sent data, I created an ASP.NET Core.

[ASP.NET Core] HomeController.cs

using Microsoft.AspNetCore.Mvc;

namespace SseSample.Controllers;

public record SampleValue(int Id, string Name);
public class WebApiController: Controller
{
    private readonly ILogger<WebApiController> logger;
    public WebApiController(ILogger<WebApiController> logger)
    {
        this.logger = logger;
    }
    [HttpGet]
    [Route("/api/get")]
    public string GetWithQuery([FromQuery] int id, string name)
    {
        return $"Get Query ID: {id} Name: {name}";
    }
    [HttpPost]
    [Route("/api/post/query/url-encoded-content")]
    public string PostWithUrlEncodedContent([FromQuery]int id, string name)
    {
        return $"PostWithUrlEncodedContent ID: {id} Name: {name}";
    }

    [HttpPost]
    [Route("/api/post/body")]
    public string PostWithBody([FromBody] SampleValue value)
    {
        return $"PostWithBody ID: {value.Id} Name: {value.Name}";
    }
    [HttpPost]
    [Route("/api/post/form")]
    public string PostWithForm([FromForm] SampleValue value)
    {
        return $"PostWithForm ID: {value.Id} Name: {value.Name}";
    }
    [HttpPost]
    [Route("/api/post/form/file")]
    public string PostWithFileInForm([FromForm] IFormFile? file)
    {
        return $"PostWithFileInForm Name: {file?.Name} FileName: {file?.FileName} Len: {file?.Length}";
    }
}
Enter fullscreen mode Exit fullscreen mode

Sending data

GET and POST with URL paramters

I can use "FormUrlEncodedContent" to add URL paramters.

[Console] Program.cs

using System.Text;
using System.Text.Json;
using WebAccessSample;

const string BaseUrl = "http://localhost:5056";
using var httpClient = new HttpClient();
var urlParams = new Dictionary<string, string>{
    { "id", "3" },
    { "name", "hello" }
};
var encodedParams = new FormUrlEncodedContent(urlParams);
var paramText = await encodedParams.ReadAsStringAsync();

Console.WriteLine(paramText);
var getResponse = await httpClient.GetAsync($"{BaseUrl}/api/get?{paramText}");
Console.WriteLine($"/api/get {await getResponse.Content.ReadAsStringAsync()}");

var postWithUrlEncodedContentResponse = await httpClient.PostAsync($"{BaseUrl}/api/post/query/url-encoded-content?{paramText}", 
    new StringContent("", Encoding.UTF8, @"text/plain"));
Console.WriteLine($"/api/post/query/url-encoded-content {await postWithUrlEncodedContentResponse.Content.ReadAsStringAsync()}");
Enter fullscreen mode Exit fullscreen mode

Results

id=3&name=hello
/api/get Get Query ID: 3 Name: hello
/api/post/query/url-encoded-content PostWithUrlEncodedContent ID: 3 Name: hello
Enter fullscreen mode Exit fullscreen mode

I also can post like below.
But I have to remove "[FromQuery]" from "PostWithUrlEncodedContent" of the ASP.NET Core application to receive "id" value.

[Console] Program.cs

...
var postWithUrlEncodedContentResponse = await httpClient.PostAsync($"{BaseUrl}/api/post/query/url-encoded-content?{paramText}", encodedParams);
Console.WriteLine($"/api/post/query/url-encoded-content {await postWithUrlEncodedContentResponse.Content.ReadAsStringAsync()}");
Enter fullscreen mode Exit fullscreen mode

POST with HTTP request body

SampleValue.cs

namespace WebAccessSample;
public record SampleValue(int Id, string Name);
Enter fullscreen mode Exit fullscreen mode

[Console] Program.cs

...
var sampleValue = new SampleValue(Id: 4, Name: "world");
var sampleValueJson = JsonSerializer.Serialize(sampleValue);
var stringData = new StringContent(sampleValueJson, Encoding.UTF8, @"application/json");

var postWithBodyResponse = await httpClient.PostAsync($"{BaseUrl}/api/post/body", stringData);
Console.WriteLine($"/api/post/body {await postWithBodyResponse.Content.ReadAsStringAsync()}");
Enter fullscreen mode Exit fullscreen mode

Results

...
/api/post/body PostWithBody ID: 4 Name: world
Enter fullscreen mode Exit fullscreen mode

POST with Form data

I can send JSON values as HTTP request body and receive deserialized value in the ASP.NET Core application, but I can't do the same with "MultipartFormDataContent".

[Console] Program.cs

...
var multiFormData = new MultipartFormDataContent();
// I couldn't do this
multiFormData.Add(stringData, "value");

var postWithFormResponse = await httpClient.PostAsync($"{BaseUrl}/api/post/form", multiFormData);
Console.WriteLine($"/api/post/form {await postWithFormResponse.Content.ReadAsStringAsync()}");
Enter fullscreen mode Exit fullscreen mode

Results

...
/api/post/form PostWithForm ID: 0 Name: 
Enter fullscreen mode Exit fullscreen mode

I should add values like below.


var multiFormData = new MultipartFormDataContent();
// OK
multiFormData.Add(new StringContent(sampleValue.Id.ToString()), "value.Id");
multiFormData.Add(new StringContent(sampleValue.Name), "value.Name");

var postWithFormResponse = await httpClient.PostAsync($"{BaseUrl}/api/post/form", multiFormData);
Console.WriteLine($"/api/post/form {await postWithFormResponse.Content.ReadAsStringAsync()}");
Enter fullscreen mode Exit fullscreen mode

Results

...
/api/post/form PostWithForm ID: 4 Name: world
Enter fullscreen mode Exit fullscreen mode

I also receive the JSON value as string.
After receiving it, I can manually deserialize it.

[Console] Program.cs

...
var multiFormData = new MultipartFormDataContent();
// OK
multiFormData.Add(stringData, "value");

var postWithFormResponse = await httpClient.PostAsync($"{BaseUrl}/api/post/form", multiFormData);
Console.WriteLine($"/api/post/form {await postWithFormResponse.Content.ReadAsStringAsync()}");
Enter fullscreen mode Exit fullscreen mode

[ASP.NET Core] HomeController.cs

...
    [HttpPost]
    [Route("/api/post/form")]
    public string PostWithForm([FromForm] string value)
    {
        var v = JsonSerializer.Deserialize<SampleValue>(value);
        return $"PostWithForm ID: {v?.Id} Name: {v?.Name}";
    }
...
Enter fullscreen mode Exit fullscreen mode

Results

...
/api/post/form PostWithForm ID: 4 Name: world
Enter fullscreen mode Exit fullscreen mode

POST with file data

[Console] Program.cs

...
var multiFormFileData = new MultipartFormDataContent();
byte[] fileData;
using(var memoryStream = new MemoryStream())
{
    using(var fileStream = new FileStream(@"./pics.png", FileMode.Open))
    {
        await fileStream.CopyToAsync(memoryStream);
    }
    fileData = memoryStream.ToArray();
}
// To send file data, I have to add "fileName"
multiFormFileData.Add(new ByteArrayContent(fileData), "file", "pics.png");

var postWithFormFileResponse = await httpClient.PostAsync($"{BaseUrl}/api/post/form/file", multiFormFileData);
Console.WriteLine($"/api/post/form/file {await postWithFormFileResponse.Content.ReadAsStringAsync()}");
Enter fullscreen mode Exit fullscreen mode

Results

...
/api/post/form/file PostWithFileInForm Name: file FileName: pics.png Len: 3872061
Enter fullscreen mode Exit fullscreen mode

Resources

Top comments (0)