Intereting Posts
Как найти файл базы данных на виртуальном устройстве Android? AsyncTask возвращает список для активности Используя google map v2 или v3 в приложении Android? Почему этот синтаксический анализ SimpleDataFormat не работает на Android? Есть ли преимущества использования FusedLocationProviderApi над LocationManager? Неожиданная ошибка при обработке файла hprof: null Отсутствуют данные электронной торговли и код отслеживания ошибок Как играть в потоковое видео RTSP (MPEG4, базовая линия) с камеры с видеообъявлением Android? Скрыть значок запуска приложения в строке заголовка, когда активность начинается с android Сброс и база данных SQLite на Android Java.lang.NoSuchMethodError: android.os.Bundle.getString Тестирование жизненного цикла и восстановления приложений приложений Android при достижении пустого состояния процесса Не удалось выполнить компиляцию AAPT2: неверный размер на Android 3.0 Canary 1 Смещение / перемещение вкладки в сочетании с ScrollView? Как установить размер ViewPager

Модернизация 2 не может загрузить файл с двумя дополнительными отдельными строковыми параметрами

Прочтите править в нижней части вопроса для возможного альтернативного решения, пока решение не будет найдено .

Это успешный почтовый файл с двумя параметрами с помощью POSTMan. Я пытаюсь сделать то же самое с модернизацией, но получаю BadRequest.

Настройки PostMan:

Введите описание изображения здесь

Информация о сети Chrome: Введите описание изображения здесь

Теперь вот как я делаю это в Android, но не могу:

Интерфейс службы дооснащения:

@Multipart @POST("jobDocuments/upload") Call<ResponseBody> upload(@Part("file") MultipartBody.Part file,@Part("folder") MultipartBody.Part folder,@Part("name") MultipartBody.Part name); 

Это мой метод @Background для запуска сетевого запроса с созданным выше сервисом

 CustDataClient service = ServiceGenerator.createService(CustDataClient.class); File file = new File(fileUri.getPath()); // create RequestBody instance from file RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file); MultipartBody.Part fileData = MultipartBody.Part.createFormData("file", fileName, requestFile); MultipartBody.Part folder = MultipartBody.Part.createFormData("folder", "LeadDocuments"); MultipartBody.Part name = MultipartBody.Part.createFormData("name", fileName); // finally, execute the request Call<ResponseBody> call = service.upload(fileData,folder,name); try { Response<ResponseBody> rr = call.execute(); ResponseBody empJobDocsResult = rr.body();//Bad Request here :( Log.v("Upload", "success"); } catch (Exception ex) { Log.e("Upload error:", ex.getMessage()); } 

Вот мой метод Web Api:

  [Route("upload")] [HttpPost] public IHttpActionResult Upload() { if (HttpContext.Current.Request.Files.AllKeys.Any()) { // Get the uploaded image from the Files collection var httpPostedFile = HttpContext.Current.Request.Files["file"]; if (httpPostedFile != null) { // Validate the uploaded image(optional) var folder = HttpContext.Current.Request.Form["folder"]; var fileName = HttpContext.Current.Request.Form["name"]; fileName = string.IsNullOrEmpty(fileName) ? httpPostedFile.FileName : fileName; // Get the complete file path var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Files/" + folder), fileName); // Save the uploaded file to "UploadedFiles" folder httpPostedFile.SaveAs(fileSavePath); return Ok(new OkMessage { Message = "File uploaded successfully", Path = "/Files/" + folder + "/" + fileName }); } } return BadRequest("File not uploaded"); } 

Пожалуйста, помогите, где я ошибаюсь и как этого добиться, есть ли простая альтернатива модернизации?

[Edit] Этот код работает успешно, благодаря koush / ion :

 Ion.with(getContext()) .load("POST", "http://www.dgheating.com/api/jobDocuments/upload") .setMultipartParameter("folder", "LeadDocuments") .setMultipartParameter("name", fileName) .setMultipartFile("file", new File(imagePath)) .asJsonObject() .setCallback(...); 

Итак, надеюсь, что уже не слишком поздно, и если так – это может помочь кому-то еще 🙂 мои 2 цента об этом – после того, как у меня была такая же проблема:

Определение службы, используя только @Part (изменять имена полей в соответствии с тем, что ожидает ваш сервер)

 //Single image MultiPart @Multipart @POST("user/imageupload") Call<ResponseBody> upload(@Part("userfile") RequestBody file, @Part("userid") RequestBody description); 

И для волшебного трюка я ссылаюсь на обе части, как на RequestBody , используя MediaType.parse() для каждого из них с собственным типом, опираясь на определение @Multipart для самого запроса, нет необходимости в материалах form-data , То же самое работает для нескольких файлов и нескольких полей:

 private static final String IMG_JPEG = "image/jpeg"; private static final String TXT_PLAIN = "text/plain"; public void uploadImageMultipart(Uri uri, final CustomEventListener<String> listener) { RequestBody fileBody; RequestBody textBody; File file = new File(uri.getPath()); Call<ResponseBody> requestCall; fileBody = RequestBody.create(okhttp3.MediaType.parse(IMG_JPEG), file); textBody = RequestBody.create(okhttp3.MediaType.parse(TXT_PLAIN), String.valueOf(SettingsManager.getUserID())); requestCall = serviceCaller.upload(fileBody, textBody); requestCall.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> rawResponse) { try { String response = rawResponse.body().string(); //from here it's your show.... listener.getResult("Got it"); } catch (Exception e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable throwable) { } }); } 

(Я использую прослушиватель, чтобы вернуть ответ обратного вызова в другую часть приложения (например, вызывающую активность)).

Это определенно отправляет файл / с и текстовое поле, другие проблемы, вероятно, будут связаны с сервером.

Надеюсь это поможет!

Я столкнулся с подобной проблемой: Android с Retrofit2 OkHttp3 – Ошибка многопоточного POST

Я решил свою проблему после принятия предложения @TommySM. Если вам все еще не ясно, я думаю, что это решение:

 @Multipart @POST("jobDocuments/upload") Call<ResponseBody> upload( @Part MultipartBody.Part file, @Part("folder") RequestBody folder, @Part("name") RequestBody name); File file = new File(fileUri.getPath()); // Assume your file is PNG RequestBody requestFile = RequestBody.create(MediaType.parse("image/png"), file); MultipartBody.Part fileData = MultipartBody.Part.createFormData("file", fileName, requestFile); RequestBody folder = RequestBody.create( MediaType.parse("text/plain"), "LeadDocuments"); RequestBody name = RequestBody.create( MediaType.parse("text/plain"), fileName); // finally, execute the request Call<ResponseBody> call = service.upload(fileData, folder, name); 

Важной частью является использование MediaType.parse("text/plain") для параметра MediaType of String (я считаю, что ваш случай: параметр folder & name), используя okhttp3.MultipartBody.FORM является ошибкой.

Смотрите эти скриншоты для сравнения:

1) Проблемная POST

Введите описание изображения здесь

2) Исправить POST

Введите описание изображения здесь

Используя Retrofit 2, вам нужно использовать классы RequestBody OkHttp или MultipartBody.Part и инкапсулировать ваш файл в тело запроса. Давайте посмотрим на определение интерфейса для загрузки файлов. Вы видели https://futurestud.io/blog/retrofit-2-how-to-upload-files-to-server

Интерфейс для дооснащения (API)

 public interface API { String NAME = "name"; String FOLDER = "folder"; @Multipart @POST("/api/jobDocuments/upload") Call<JsonResponse> uploadFile( @Part(NAME) String name, @Part(FOLDER) String folder, @Part MultipartBody.Part file); } 

Класс ответа (JsonResponse)

 public class JsonResponse { @SerializedName("$id") public String id; @SerializedName("Message") public String message; @SerializedName("Path") public String path; public JsonResponse(String id, String message, String path) { this.id = id; this.message = message; this.path = path; } } 

API-вызов из приложения

 Retrofit retrofit; private void postImage() { String URL = "http://www.dgheating.com/"; //your file location File file = new File(Environment.getExternalStorageDirectory() + "/Image.png"); //parameters String NAME = file.getName(); String FOLDER = "LeadDocuments"; String FILE = "file"; retrofit = new Retrofit.Builder() .baseUrl(URL) .addConverterFactory(GsonConverterFactory.create(new Gson())) .build(); API api = retrofit.create(API.class); RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); MultipartBody.Part part = MultipartBody.Part.createFormData(FILE, NAME, requestBody); Call<JsonResponse> call = api.uploadFile(NAME, FOLDER, part); call.enqueue(new Callback<JsonResponse>() { @Override public void onResponse(Call<JsonResponse> call, Response<JsonResponse> response) { //response.body() null //response.code() 500 //https://github.com/square/retrofit/issues/1321 Converter<ResponseBody, JsonResponse> errorConverter = retrofit.responseBodyConverter(JsonResponse.class, new Annotation[0]); try { JsonResponse jsonResponse = errorConverter.convert(response.errorBody()); Log.e("error", "id:" + jsonResponse.id); //1 Log.e("error", "message:" + jsonResponse.message); //An error has occurred Log.e("error", "path:" + jsonResponse.path); //null } catch (IOException ignored) { } } @Override public void onFailure(Call<JsonResponse> call, Throwable t) { } }); } 

Ошибка в полях из-за любой из этих проблем сервера

  1. Google
  2. Ответ HTTP 500 с использованием модификации, но запрос на отправку через Postman дает желаемый ответ
  3. Как получить тело ответа для модификации исключения?
  4. Повторная установка SocketTimeoutException (и / или ошибка http 500) на http-POST

Похоже, что ваше определение сервиса неверно. Пытаться

 @Multipart @POST("jobDocuments/upload") Call<ResponseBody> upload(@Part("file") MultipartBody.Part file,@Part("folder") RequestBody folder,@Part("name") RequestBody name); 

а также

 RequestBody folder = RequestBody.create( MediaType.parse("multipart/form-data"), "LeadDocuments"); RequestBody name = RequestBody.create( MediaType.parse("multipart/form-data"), filename); 

В методе @Background. Все это предполагает, что вы используете Retrofit2.