【问题标题】:Send file from Android Kotlin to C# using POST使用 POST 将文件从 Android Kotlin 发送到 C#
【发布时间】:2021-08-07 17:21:24
【问题描述】:

我们有两个应用程序:一个 C# REST-API 和一个 Kotlin Android 应用程序,我们使用 Google Platform Cloud Bucket 来托管图像。

Android 应用会上传一张图片,但 C# REST-API 需要上传到谷歌云平台。

这是将文件上传到 Google Cloud Buckets 的有效 C# 代码:

        [HttpPost]
        [Route("upload")]
        public IActionResult Upload()
        {
            var storageClient = StorageClient.Create(google_credentials);

            string fileToUpload ="/Users/niel/Downloads/new_cat.jpg";
            
            using (var fileStream = new FileStream(fileToUpload, FileMode.Open,
                FileAccess.Read, FileShare.Read))
            {
                storageClient.UploadObject("test_storage_fotos", "new_cat", "image/jpeg", fileStream);
            }
            Console.WriteLine("uploaded the file successfully");

            return Ok();
        }
        

现在我需要将 fileToUpload 替换为 POST 请求中的内容。有没有办法做到这一点?图片来自 Android 应用 > C# API > Google Buckets?从 C# API 到 Google Buckets 的链接已经生效。

在 Kotlin 中有没有办法以某种方式获取图像的字节串,将其发布到我的 C# API,后者获取内容并将其放入 FileStream?我可以使用storageClient.UploadObject 上传FileStream 吗?有这种可能吗?

谢谢!

【问题讨论】:

  • 您可以在 Android 中使用 Retrofit 来发送任何文件,此外,您应该有一个 Endpoint 来接收来自 Android 的文件。
  • 但我不想真正拥有端点来保存文件。我想将文件的内容发送到服务器,然后服务器将其传递给 Google Buckets。

标签: c# android file-upload


【解决方案1】:

是的,你绝对可以做到这一点。只需通过具有 multipart/form-data 内容类型的 http 协议将文件发送到服务器。

在 kotlin 中,您可以使用 ktor 或任何其他 http 库来执行此操作。 对于 ktor,您需要添加实现依赖项

implementation "io.ktor:ktor-client-android:1.5.4"

您可能还需要在 AndroidManifest.xml 中添加额外的权限

<uses-permission android:name="android.permission.INTERNET" />

然后你可以用这个sn-p发送一个文件。注意 imageUri 是一个内容 uri,对于文件 uri,代码会有点不同

private fun getFileName(resolver: ContentResolver, uri: Uri): String {
    val returnCursor: Cursor = resolver.query(uri, null, null, null, null)!!
    val nameIndex: Int = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
    returnCursor.moveToFirst()
    val name: String = returnCursor.getString(nameIndex)
    returnCursor.close()
    return name
}

suspend fun postAndImage(imageUri: Uri, uploadEndPoint: String) {
    val client = HttpClient(Android)

    val cr = applicationContext.contentResolver
    if(cr.getType(imageUri) == null) {
        //process error
        return
    }

    val stream = cr.openInputStream(imageUri)

    if(stream == null) {
        //process error
        return
    }

    val response: HttpResponse = client.submitFormWithBinaryData(
        url = uploadEndPoint,
        formData = formData {
            append("image", InputProvider { stream.asInput() }, Headers.build {
                append(HttpHeaders.ContentType, cr.getType(imageUri)!!)
                append(HttpHeaders.ContentDisposition, "filename=${getFileName(cr, imageUri)}")
            })
        }
    )

    stream.close()

    //process response
}

你需要稍微修改你的上传功能

[HttpPost]
[Route("upload")]
//the name of the argument must match the key that you pass in "append" function
public async Task<IActionResult> Post(IFormFile image)
{            
    var storageClient = StorageClient.Create(google_credentials);

    using (var stream = image.OpenReadStream())
    {           
        //it's also possible to get original file name from file name property
        var fileName = Guid.NewGuid() + "." + Path.GetExtension(image.FileName);
            
        //assuming bucket is already created
        var storageObject = await storageClient
                    .UploadObjectAsync("test_storage_fotos", fileName, "image/jpeg", stream);
        //save information about a storage object in database
    }

    return Ok();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-23
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多