Send image with HttpClient to POST WebApi and consume the data

前端 未结 2 1912
春和景丽
春和景丽 2021-01-27 14:58

My HttpClient sends the image with PostAsync. I am not really sure what to do now since this is my first REST Api and I can\'t really adapt the things

相关标签:
2条回答
  • 2021-01-27 15:16

    You're going fine until you're trying to retrieve the image data, I'm afraid.

    According to your question:

    How do I read the image data and write it to a file?

    All you want to do is getting the file's data and its file name and sending it to your service.

    I would personally create an UploadedFile class on both sides (client and service side), having the file's name and its data, so:

    public class UploadedFile
    {
        public string FileFullName { get; set; }
        public byte[] Data { get; set; }
    
        public UploadedFile(string filePath)
        {
            FileFullName = Path.GetFileName(Normalize(filePath));
            Data = File.ReadAllBytes(filePath);
        }
    
        private string Normalize(string input)
        {
            return new string(input
                    .Normalize(System.Text.NormalizationForm.FormD)
                    .Replace(" ", string.Empty)
                    .ToCharArray()
                    .Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                    .ToArray());
        }
    }
    

    Then you will need, for example, the NewtonSoft's JsonConvert in order to serialize the object and send it through.

    So now you would be able to send your data async:

    public async Task SendDataAsync(string fullFilePath)
    {
        if (!File.Exists(fullFilePath))
            throw new FileNotFoundException();
        var data = JsonConvert.SerializeObject(new UploadedFile(fullFilePath));
        using (var client = new WebClient())
        {
            client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
            await client.UploadStringTaskAsync(new Uri("http://localhost:64204/api/upload/"), "POST", data);
        }
    }
    

    Now, make sure you correctly handle the request on the server side. If for whatever reason the parameters doesn't match it won't enter into the method (remember having the same model/class - UploadedFile on the service as well).

    On the service, just change the arguments of your method and perform something "like this":

    [HttpPost]
    public HttpResponseMessage Upload(UploadedFile file)
    {
        if (!ModelState.IsValid)
            ...
            
        if (file == null)
            ...
        string destinationPath = Path.Combine(_whateverPath, file.FileFullName);
        File.WriteAllBytes(destinationPath, file.Data);
    }
    

    Hope it helped you having an idea about what to do and what you're actually doing wrong. I've exposed something similar based in my experience.

    EDIT: I've actually uploaded an example with both sides working: a simple .NET Core console app which retrieves a file and sends it through POST and a basic WebAPI2 service with a simple controller to retrieve the data. Both ready to go and tested working! Download it here.

    Enjoy.

    0 讨论(0)
  • 2021-01-27 15:18

    1.Your controller should look like this:

    //For .net core 2.1
    [HttpPost]
    public IActionResult Index(List<IFormFile> files)
    {
        //Do something with the files here. 
        return Ok();
    }
    
    //For previous versions
    
    [HttpPost]
    public IActionResult Index()
    {
        var files = Request.Form.Files;
        //Do something with the files here. 
        return Ok();
    }
    

    2.To upload a file you can also use Multipart content:

            public async Task UploadImageAsync(Stream image, string fileName)
            {
                HttpContent fileStreamContent = new StreamContent(image);
                fileStreamContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") { Name = "file", FileName = fileName };
                fileStreamContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
                using (var client = new HttpClient())
                using (var formData = new MultipartFormDataContent())
                {
                    formData.Add(fileStreamContent);
                    var response = await client.PostAsync(url, formData);
                    return response.IsSuccessStatusCode;
                }
             }
    

    3.If you are uploading large files you should consider streaming the files instead, you can read about it here

    0 讨论(0)
提交回复
热议问题