Search code examples
c#-4.0httpclientasp.net-core-webapixamarin-forms-4

POST form-data with Image File using C#


I'm trying to send a post request contain data and image file. but when I send uing my code below, I getting an error. Please see my code below for on client side.

    public async Task<HttpContent> PostRequestAsync(string requestUri)
    {
        string jsonString = string.Empty;
        StringContent stringJsonContent = default(StringContent);
        HttpResponseMessage requestResponse = new HttpResponseMessage();

        try
        {
            stringJsonContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
            requestResponse = await this.httpClient.PostAsync(requestUri, stringJsonContent);

            if (requestResponse.IsSuccessStatusCode)
            {
                return requestResponse?.Content;
            }
            else if (requestResponse.StatusCode == HttpStatusCode.InternalServerError)
            {
            }
            else if (requestResponse.StatusCode == HttpStatusCode.Unauthorized)
            {
            }

        }
        catch (Exception ex)
        {
            throw ex.InnerException;
        }
        return requestResponse?.Content;
    }
}

and on WebAPI the controller looks below

    [HttpPost]     
    public async Task<ActionResult> UpdateProfile([FromForm] UpdateProfile updateProfile)

Model is

public class UpdateProfile:BaseModel
{

    public string firstName { get; set; }
    public string lastName { get; set; }
    public IFormFile Image { get; set; }
}

but in POSTMAN I'm successfully upload the file using below, so that I have a feeling the there's wrong with my code in client side. Anyone can suggest what I need to add on my code to work? I'm getting an error and not able to send the request.

POSTMAN


Solution

  • In your client code, you don’t use the form object to transmit data. StringContent stores the value of the form instead of the key. You can use the MultipartFormDataContent object to transfer all forms and files. In addition, I give an example code.

    The code in client.

    class Program
    {
        static async Task Main(string[] args)
        {
           await PostRequestAsync(@"D:\upload\1.jpg", new HttpClient(), "https://localhost:44370/api/UpdateProfile");
        }
        public static async Task<string> PostRequestAsync(string filePath,HttpClient _httpClient,string _url)
        {
            if (string.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentNullException(nameof(filePath));
            }
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"File [{filePath}] not found.");
            }
    
            //Create form
            using var form = new MultipartFormDataContent();
            var bytefile = AuthGetFileData(filePath);
            var fileContent = new ByteArrayContent(bytefile);
            fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
            form.Add(fileContent, "Image", Path.GetFileName(filePath));
    
            //the other data in form
            form.Add(new StringContent("Mr."), "firstName");
            form.Add(new StringContent("Loton"), "lastName");
            form.Add(new StringContent("Names--"), "Name");
            var response = await _httpClient.PostAsync($"{_url}", form);
            response.EnsureSuccessStatusCode();
            var responseContent = await response.Content.ReadAsStringAsync();
    
            return responseContent;
        }
    
        //Convert file to byte array
        public static byte[] AuthGetFileData(string fileUrl)
        {
            using (FileStream fs = new FileStream(fileUrl, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                byte[] buffur = new byte[fs.Length];
                using (BinaryWriter bw = new BinaryWriter(fs))
                {
                    bw.Write(buffur);
                    bw.Close();
                }
                return buffur;
            }
        }
    }
    

    The action in WebApi

    [ApiController]
    [Route("[controller]")]
    public class ApiController:Controller
    {
        [HttpPost("get")]
        public string get([FromForm]UpdateProfile updateProfile)
        {
            return "get";
        }
        [HttpPost("UpdateProfile")]
        public async Task<ActionResult> UpdateProfile([FromForm] UpdateProfile updateProfile)
        {
            return Json("The result data "); 
        }
    }
    

    The model

    public class UpdateProfile : BaseModel
    {
        public string firstName { get; set; }
        public string lastName { get; set; }
        public IFormFile Image { get; set; }
    }
    public class BaseModel
    {
        public string Name { get; set; }
    }
    

    result: enter image description here