使用 POST 将文件从 Android Kotlin 发送到 C#
Send file from Android Kotlin to C# using POST
我们有两个应用程序:一个 C# REST-API 和一个 Kotlin Android 应用程序,我们使用 Google Platform Cloud Bucket 来托管图像。
Android应用会上传图片,但C#REST-API需要上传到Google云平台
这是将文件上传到 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();
}
现在我需要用 POST 请求中的内容替换 fileToUpload
。有没有办法做到这一点?图片来自 Android app > C# API > Google Buckets?从 C# API 到 Google Buckets 的 link 已经在工作了。
Kotlin 中有没有办法以某种方式获取图像的字节串,post 将其发送到我的 C# API,后者获取内容并将其放入 FileStream
?我可以使用 storageClient.UploadObject
上传 FileStream
吗?有这种可能吗?
谢谢!
是的,你绝对可以做到这一点。只需通过 http 协议将文件发送到服务器,内容类型为 multipart/form-data。
在 kotlin 中,您可以使用 ktor 或任何其他 http 库来执行此操作。
对于 ktor,您需要添加一个实现依赖项
implementation "io.ktor:ktor-client-android:1.5.4"
您可能还需要在 AndroidManifest.xml
中添加额外的权限
<uses-permission android:name="android.permission.INTERNET" />
然后您可以发送包含此代码段的文件。请注意,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();
}
我们有两个应用程序:一个 C# REST-API 和一个 Kotlin Android 应用程序,我们使用 Google Platform Cloud Bucket 来托管图像。
Android应用会上传图片,但C#REST-API需要上传到Google云平台
这是将文件上传到 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();
}
现在我需要用 POST 请求中的内容替换 fileToUpload
。有没有办法做到这一点?图片来自 Android app > C# API > Google Buckets?从 C# API 到 Google Buckets 的 link 已经在工作了。
Kotlin 中有没有办法以某种方式获取图像的字节串,post 将其发送到我的 C# API,后者获取内容并将其放入 FileStream
?我可以使用 storageClient.UploadObject
上传 FileStream
吗?有这种可能吗?
谢谢!
是的,你绝对可以做到这一点。只需通过 http 协议将文件发送到服务器,内容类型为 multipart/form-data。
在 kotlin 中,您可以使用 ktor 或任何其他 http 库来执行此操作。 对于 ktor,您需要添加一个实现依赖项
implementation "io.ktor:ktor-client-android:1.5.4"
您可能还需要在 AndroidManifest.xml
中添加额外的权限<uses-permission android:name="android.permission.INTERNET" />
然后您可以发送包含此代码段的文件。请注意,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();
}