简体   繁体   English

使用HttpClient发送图像到POST WebApi并使用数据

[英]Send image with HttpClient to POST WebApi and consume the data

My HttpClient sends the image with PostAsync . 我的HttpClient使用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 I sorted out in other posts yet. 我不太确定现在该怎么做,因为这是我的第一个REST Api,并且我还不能真正适应在其他帖子中整理的内容。 Hopefully you guys can help me out and can give me a direction. 希望你们能帮助我,并给我一个方向。

public async Task SendImage(string fullFileName, string fileName)
    {            
        var client = new HttpClient();
        client.BaseAddress = new Uri("http://x.x.x.x");

        var content = new StringContent(fullFileName, Encoding.UTF8, "image/jpg");
        HttpResponseMessage response = await client.PostAsync($"/values/file/{fileName}", content);
    }

I have several questions about the POST function. 我对POST功能有几个疑问。 First of all I can successfully access it with PostMan and the fileName is correct. 首先,我可以使用PostMan成功访问它,并且fileName是正确的。

How do I read the image data and write it to a file? 如何读取图像数据并将其写入文件?

[HttpPost("file/{fileName}")]
public void Upload(string fileName)
{        
    Debug.Write(fileName);
}

EDIT: 编辑:

I setup my environment and I can now send a post via the internet to my published Web Api. 我设置了环境,现在可以通过互联网将帖子发送到我发布的Web Api。 On my app just nothing happens. 在我的应用程序上什么也没有发生。 For now I just tried to get something of a message to work on but I dont getting one. 就目前而言,我只是想获得一些信息,但我没有得到。

[HttpPost("file/{fileName}")]
public HttpResponseMessage Upload(UploadedFile fileName)
{
    Debug.Write(fileName);
    if (!ModelState.IsValid)
    {

    }
    if (fileName == null)
    {

    }

    string destinationPath = Path.Combine(@"C:\", fileName.FileFullName);
    System.IO.File.WriteAllBytes(destinationPath, fileName.Data);
    HttpResponseMessage rm = new HttpResponseMessage();
    rm.StatusCode = HttpStatusCode.OK;
    return rm;
}

1.Your controller should look like this: 1.您的控制器应如下所示:

//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: 2.要上传文件,您还可以使用多部分内容:

        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 3.如果要上传大文件 ,则应考虑流式传输文件,可以在此处阅读

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: 我将在两边(客户端和服务端)亲自创建一个UploadedFile类,并具有文件名和数据,因此:

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. 然后,您将需要使用例如NewtonSoft的JsonConvert来序列化对象并将其发送通过。

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). 如果由于某种原因参数不匹配,它将不会进入方法(请记住具有相同的模型/类-服务上也具有UploadedFile )。

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. 编辑 :我实际上已经上传了一个示例,双方都可以工作:一个简单的.NET Core控制台应用程序,该应用程序检索文件并通过POST发送该文件,以及具有简单控制器的基本WebAPI2服务,以检索数据。 Both ready to go and tested working! 两者都准备就绪,可以测试工作了! Download it here . 在这里下载。

Enjoy. 请享用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM