1

I need to receive a content together with a byte array in a c# ASP.NET Core Web API application.

**--HttpClient (console Application)**  

                Dictionary<int, byte[]> fileparts = new Dictionary<int, byte[]>();
                int bufferSize = 1000 * 1024;

                byte[] buffer;
                string filePath = @"D:\Extra\Songs\test.mp3";
                using (FileStream fileData = File.OpenRead(filePath))
                {
                    int index = 0;
                    int i = 1;
                    while (fileData.Position < fileData.Length)
                    {

                        if (index + bufferSize > fileData.Length)
                        {
                            buffer = new byte[(int)fileData.Length - index];
                            fileData.Read(buffer, 0, ((int)fileData.Length - index));
                        }
                        else
                        {
                            buffer = new byte[bufferSize];
                            fileData.Read(buffer, 0, bufferSize);
                        }

                        fileparts.Add(i, buffer);
                        index = (int)fileData.Position;
                        i++;
                    }
                }
                
 while (fileparts.Count() != 0)
 {               
      var data = fileparts.First();          
  var fileContent = new ByteArrayContent(data);//byte content
    fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "test" };
                        fileContent.Headers.Add("id", id);
                        fileContent.Headers.Add("name", name);
                        fileContent.Headers.Add("length", length);
                        if (fileparts.Count() == 1)
                          fileContent.Headers.Add("IsCompleted", "true");
                        else
                          fileContent.Headers.Add("IsCompleted", "false");
                          
                    using (var content = new MultipartFormDataContent())
                    {
                       content.Add(fileContent);
                       // Make a call to Web API 
                        var result = client.PostAsync("/api/file", fileContent).Result;
                        if (result.StatusCode == System.Net.HttpStatusCode.OK)
                            fileparts.Remove(data.Key);
                    }

**--WebApi Core ApiController**

    public class FileController : Controller
    {
        [HttpPost]
        public async Task<IActionResult> Post()
        {
    /*i need to get the content here , for some reason existing .NET libraries does not work here
    like 
        MultipartMemoryStreamProvider provider = new MultipartMemoryStreamProvider();
        FilePart part = null;
       
        await Request.Content.ReadAsMultipartAsync(provider); -- request.content not available 
        using (Stream fileStream = await provider.Contents[0].ReadAsStreamAsync())
                {
                    part = provider.Contents[0].Headers.GetData(); //public static FilePart GetData name,length,id 
                    part.Data = fileStream.ReadFully();
    */    
    }
the back end I have working but can't find a way of the new asp.net core controller parsing fileobject and data from client post through to the service! Any ideas would be greatly appreciated as always...

4
  • you are passing the ByteArrayContent to the controller but not the MultipartFormDataContent are you sure about this? Commented Sep 27, 2017 at 16:20
  • in this line var result = client.PostAsync("/api/file", fileContent).Result; Commented Sep 27, 2017 at 16:20
  • Hi @Niladri yes It's a mistake, it should be var result = client.PostAsync("/api/file", content).Result; not fileContent Commented Sep 27, 2017 at 17:06
  • I have updated my answer please check Commented Sep 27, 2017 at 17:30

2 Answers 2

3

You can modify your controller action method like below to accept ByteArrayContent OR MultipartFormDataContent as required. I have used [FromBody] attribute for the model binding in POST.

Here is more info on [FromBody]

https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding

public class FileController : Controller
    {
        [HttpPost]
        public async Task<IActionResult> Post([FromBody] MultipartFormDataContent content)
        {
         MultipartMemoryStreamProvider provider = new MultipartMemoryStreamProvider();
        FilePart part = null;
         // access the content here 
         await content.ReadAsMultipartAsync(provider);
        // rest of the code
       }
   }

as discussed before you should be using content to post to this API like below

var result = client.PostAsync("/api/file", content).Result;

Sign up to request clarification or add additional context in comments.

9 Comments

With [FromBody] attribute client exit with 'UnsupportedMediaType', it seems not reach the server side POST.
@Lakmal which version of web api are you using ?
@Lakmal have you changed it to var result = client.PostAsync("/api/file", content).Result;
you mean "Microsoft.AspNet.WebApi.Client": "5.2.3", "Microsoft.AspNetCore.Mvc": "1.0.1" ?
Yes, var result = client.PostAsync("/api/file", content).Result;
|
2

I've used this sucessfully in the past:

[HttpPost]
public async Task<IActionResult> Post(IFormFile formFile)
{
    using (Stream stream = formFile.OpenReadStream())
    {
         //Perform necessary actions with file stream
    }
}

I believe you'll also need to change your client code to match the parameter name:

fileContent.Headers.Add("name", "formFile");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.