0

Currently my webAPI has the following POST endpoint:

public async Task<ActionResult<string>> AddUserImage([FromRoute] string userId, [FromHeader] bool doNotOverwrite, [FromBody] byte[] content, CancellationToken ct)

My goal is to send an image file to the endpoint. However, I cannot find a correct way to send an octect-stream or ByteArrayContent or some other type over the internet. All attempts end in an HTTP 415.

This is my best attempt to send the image over the internet:

public async Task<bool> AddOrReplaceImage(string id, string endpoint, byte[] imgBinary)
{
    if (imgBinary is null) throw new ArgumentNullException(nameof(imgBinary));

    var request = new HttpRequestMessage(HttpMethod.Post, endpoint);
    request.Headers.Add("doNotOverwrite", "false");
    request.Content = JsonContent.Create(imgBinary);
    // I also tried: request.Content = new ByteArrayContent(imgBinary);
    request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); // Does not seem to change a thing
            
    var apiResult = await new HttpClient().SendAsync(request); // Returns 415
    return apiResult.IsSuccessStatusCode;
}

I doubt both the parameters of the endpoint and the way I send the HTTP request. How can I simply receive and send an image over the internet?

Pradeep Kumar
  • 1,193
  • 1
  • 9
  • 21
Silas
  • 40
  • 7

1 Answers1

1
  1. Frist Solution :- Which worked in my case.

    You can try [FromForm] and IFormFile Like this :-

If controller is annotated with [ApiController] then[FromXxx] is required. For normal view controllers it can be left.

public class PhotoDetails
{
  public string id {get;set;}
  public string endpoint {get;set;}
  public IFormFile photo {get;set;}
}

public async Task<ActionResult<string>> AddUserImage([FromForm] PhotoDetails photoDetails, CancellationToken ct)

I tried this in .net core and it worked but i needed array of files so i used [FromForm] and IFormFile[] and sending from angular.

  1. Second Solution :- I tried replicate question scenario with question code. enter image description here

    and then changed the implementation and it worked. Please find the below code

         PhotoDetails photopara = new PhotoDetails();
          photopara.id = id;
          photopara.endpoint = endpoint;
          photopara.photo = imgdata;
          string json = JsonConvert.SerializeObject(photopara);
          var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
          using (var client = new HttpClient())
          {
              var response = await client.PostAsync("http://localhost:57460/WeatherForecast", stringContent);
              if (!response.IsSuccessStatusCode)
              {
                  return null;
              }
              return (await response.Content.ReadAsStreamAsync()).ToString();
          }

     public class PhotoDetails
     {
       public string id {get;set;}
       public string endpoint {get;set;}
       public byte[] photo {get;set;}
     }

In this solution, I changed IformFile to byte[] in photodetail class because httpresponsemessage creating problem.

Get Image or byte array in Post Method

enter image description here

Please try this without json serialization

 using (var client = new HttpClient())
            using (var formData = new MultipartFormDataContent())
            {
                formData.Add(idContent, "id", "param1");
                formData.Add(endpointContent, "endpoint", "file1");
                formData.Add(bytesContent, "photo", "file2");
                var response = await client.PostAsync("http://localhost:57460/WeatherForecast", formData);
                if (!response.IsSuccessStatusCode)
                {
                    return null;
                }
                return (await response.Content.ReadAsStreamAsync()).ToString();
            }

public async Task<ActionResult<int>> AddUserImage([FromForm] PhotoDetails photo, CancellationToken ct)
{
 // logic
}

Still Not working then You can try the below link also

Send Byte Array using httpclient

Pradeep Kumar
  • 1,193
  • 1
  • 9
  • 21
  • Having read this I tried `[FromForm] FormFile` and `[FromForm] byte[]`, but I still do not know how to send a FormFile properly as I always get error 415. Also, accepting a class like `PhotoDetails` is built-in in ASP.NET and would just serialize the `IFormFile photo` to who-knows what, but then I could just as well just send a base64 string. I seek a way to send and accept a bytearray directly – Silas Sep 24 '22 at 10:07
  • still you have problem or did you fix it? – Pradeep Kumar Sep 24 '22 at 12:06
  • if you are still facing problem then share your web api code and how you are sending image/file, -> what is content type -> do controller have apicontroller annotation or not. Beacuse FromForm and IFormFile worked for me .net 6 and .netcore – Pradeep Kumar Sep 24 '22 at 13:01
  • The only relevant code from my API is given in the question, all other code is not even executed. In my second attempt I changed my second block of code - that sends the request - by trying to send a MultipartFormDataContent instance, which didn't work even with tutorials. I'm afraid I cannot share more code because of an NDA agreement. All I need really is an example, so what was your code which sends the HTTP request? – Silas Sep 24 '22 at 14:14
  • ok i will try your code on my machine then get back to you as soon as possible – Pradeep Kumar Sep 24 '22 at 19:53
  • I have resolved exception in my local. Please find updated code and try second solution and let me know it work for you or not. And I am assuming you have [ApiController] and [HttpPost] annotation on controller and method. – Pradeep Kumar Sep 25 '22 at 11:36
  • Thanks a lot for your help, but this still utilizes JSON serialization. I seek a way to do this without literal characters in the http contents, but just raw bits and bytes. I believed something like ByteArrayContent was what I was looking for, but seeing your attempts to help me makes me thing that perhaps I am looking for something that does not exist. Is there a way to just rend raw bytes, without serialization? – Silas Sep 25 '22 at 13:18
  • I have updated answer please try this one also – Pradeep Kumar Sep 25 '22 at 15:47