bartjay
bartjay

Reputation: 33

C#: Posting Model from body and file as MultipartFormDataContent

I'm looking for a way to send model and image in one request. I tried to send my model from body, but I don't know how to send the file. Is there another way than sending image and model in a different files?

Here's the POST method from my API:

[HttpPost]
[Route("UploadNewEvent")]
public async Task<IActionResult> CreateNewEventAsync([FromBody] EventModel model)
{
    var file = this.Request.Form.Files.LastOrDefault();

    if (file != null)
    {
        var uploads = Path.Combine(_environment.WebRootPath, "uploads");

        using (var fileStream = new FileStream(Path.Combine(uploads, "test.jpg"), FileMode.Create))
        {
            await file.CopyToAsync(fileStream);
        }
     }

     // do sth with model later    
     return Ok();
}

And here's the code from my App:

public async Task SendNewEvent(EventModel model, MediaFile photo)
{
    var uri = $"{baseUri}api/User/Event/CreateNewEvent";

    if (photo != null)
    {
        var multipartContent = new MultipartFormDataContent();
        multipartContent.Add(new StreamContent(photo.GetStream()), "\"file\"", $"\"{photo.Path}\"");

        var httpClient = new HttpClient();               
        var jsonObject = JsonConvert.SerializeObject(model);
        var stringContent = new StringContent(jsonObject, Encoding.UTF8, "application/json");
        var httpResponseMessage = await httpClient.PostAsync(uri, stringContent);
    }
}

Upvotes: 3

Views: 4571

Answers (2)

MayankGaur
MayankGaur

Reputation: 993

I have resolved this type of issue by following code. Please let me know if you find any difficulty. In my example I have used File, Model Object and simple string will help in future.

 using Newtonsoft.Json;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace TestingProject
{
    class Program1
    {
        static void Main(string[] args)
        {
            UploadFile();
        }

        public static async Task UploadFile()
        {


            HttpClient httpClient = new HttpClient
            {
                BaseAddress = new Uri("https://google.com/")
            };


            var filepath = @"C:\Sample Documents.pdf";
            var filename = "Sample Documents.pdf";
            using (MultipartFormDataContent content = new MultipartFormDataContent())
            {
                ByteArrayContent fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(filepath));
                fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = filename };
                fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

                Request request = new Request()
                {
                    UserId = "1",
                    UserName = "test",
                    address = new AddressModel()
                    {

                        City = "test",
                        Country = "India"
                    },
                    FileDetails = fileContent





                };
                var addressSerialize = JsonConvert.SerializeObject(request.address);

                FileStream fileStream = new FileStream(filepath, FileMode.Open);
                var multipartContent = new MultipartFormDataContent();
                multipartContent.Add(new StreamContent(fileStream), "\"file\"", filepath);
                multipartContent.Add(new StringContent(request.UserId), "UserId");
                multipartContent.Add(new StringContent(request.UserName), "UserName");
                multipartContent.Add(new StringContent(addressSerialize), "address");
         



                HttpResponseMessage httpResponseMessage = await httpClient.PostAsync("upload", multipartContent).ConfigureAwait(false);
                var personResponse = await httpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);

            }

        }


        public class Request
        {
            /// <summary>
            /// userId 
            /// </summary>
            [JsonProperty(PropertyName = "userId")]
            public string UserId { get; set; }


            /// <summary>
            /// UserName 
            /// </summary>
            [JsonProperty(PropertyName = "UserName")]
            public string UserName { get; set; }


            /// <summary>
            /// docType 
            /// </summary>
            [JsonProperty(PropertyName = "FileDetails")]
            public ByteArrayContent FileDetails { get; set; }

            /// <summary>
            /// address 
            /// </summary>
            [JsonProperty(PropertyName = "address")]
            public AddressModel address { get; set; }


        }

        public class AddressModel
        {
            /// <summary>
            /// City 
            /// </summary>
            [JsonProperty(PropertyName = "City")]
            public string City { get; set; }


            /// <summary>
            /// Country 
            /// </summary>
            [JsonProperty(PropertyName = "Country")]
            public string Country { get; set; }
        }

    }
}

Upvotes: 0

Edward
Edward

Reputation: 29986

For passing Model with File parameter, you need to post data as form-data.

Follow steps below:

  1. Change FromBody to FromForm

        [HttpPost]
    [Route("UploadNewEvent")]
    public async Task<IActionResult> CreateNewEventAsync([FromForm] EventModel model)
    {
        // do sth with model later    
        return Ok();
    }
    
  2. Change client code to send form-data instead of json string

        var uri = $"https://localhost:44339/UploadNewEvent";
        FileStream fileStream = new FileStream(@"filepath\T1.PNG", FileMode.Open);
        var multipartContent = new MultipartFormDataContent();
        multipartContent.Add(new StreamContent(fileStream), "\"file\"", @"filepath\T1.PNG");
    
    
        // EventModel other fields
        multipartContent.Add(new StringContent("2"), "Id");
        multipartContent.Add(new StringContent("Tom"), "Name");
        var httpClient = new HttpClient();
        var httpResponseMessage = httpClient.PostAsync(uri, multipartContent).Result;
    
  3. EventModel

    public class EventModel
    {
    public int Id { get; set; }
    public string Name { get; set; }
    public IFormFile File { get; set; }
    }
    

Upvotes: 6

Related Questions