Недавно я работал над кодом для загрузки видео на сервер. Он отлично работает при публикации на php.
PHP-код, который отлично работает с Android:
<?php
$file_path = $_SERVER['DOCUMENT_ROOT'].'/uploads/'; //$_SERVER['DOCUMENT_ROOT'] is neccessary and slash before 'uploads'
$file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
if (move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path)) {
echo "success".$file_path;
} else{
echo "fail";
}
?>
Код ASP .Net, который возвращает ответ Not Found ServerResponse на android
[HttpPost]
public HttpResponseMessage UploadFile(HttpPostedFileBase file)
{
try
{
if (file.ContentLength > 0)
{
string _FileName = Path.GetFileName(file.FileName);
string _path = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/Videos"), _FileName);
file.SaveAs(_path);
}
return Request.CreateResponse(HttpStatusCode.OK, "success");
}
catch
{
return Request.CreateResponse(HttpStatusCode.BadRequest, "failed");
}
}
Код Android для загрузки видео
private int uploadVideo(String sourceFileUri) {
String fileName = sourceFileUri;
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File(sourceFileUri);
if (!sourceFile.isFile()) {
dialog.dismiss();
Log.e("uploadFile", "Source File not exist :" + selectedVideoPath);
runOnUiThread(new Runnable() {
public void run() {
videoURL.setText("Source File not exist :" + selectedVideoPath);
}
});
return 0;
} else {
try {
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL("http://domain.online/api/User/FileUpload");
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary = " + boundary);
conn.setRequestProperty("uploaded_file", fileName);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
final String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : " + serverResponseMessage + ": " + serverResponseCode);
if (serverResponseCode == 200) {
runOnUiThread(new Runnable() {
public void run() {
String msg = "File Upload Completed.\n\n See uploaded file here : \n\n" + serverResponseMessage;
videoURL.setText(msg);
Toast.makeText(PostNewTarget.this, "File Upload Complete.", Toast.LENGTH_SHORT).show();
}
});
} else {
runOnUiThread(new Runnable() {
public void run() {
String msg = "File Upload Completed.\n\n See uploaded file here : \n\n" + serverResponseMessage;
videoURL.setText(msg);
Toast.makeText(PostNewTarget.this, "File Upload Complete.", Toast.LENGTH_SHORT).show();
}
});
}
// close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
dialog.dismiss();
ex.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(PostNewTarget.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
} catch (Exception e) {
dialog.dismiss();
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(PostNewTarget.this, "Got Exception : see logcat ", Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload f - s Exception", "Exception : " + e.getMessage(), e);
}
dialog.dismiss();
return serverResponseCode;
}
}
Есть ли лучший способ получить видеофайл в .Net? Это как-то связано с IIS? Что мне здесь не хватает
Я спросил об этом. Переменная serverResponseMessage содержит значение Not Found, если serverResponseCode не равен 200
Тогда что это, если не 200?
Вы пишете в conn.getOutputStream (). Но сервер тоже вернет страницу, если это обычный сервер. Вы не читаете этот ответ. Вы должны прочитать все из conn.getInputStream ().
Я пытаюсь загрузить видео, которое не загружается на сервер, оно отвечает только серверным ответом «Не найдено».
Нет. Сервер отвечает «успешно» или «не удалось». Что из двух вы получите? Вы не получите его, поскольку не читаете из входящего потока. Вы должны это сделать!
Решил проблему. На самом деле мы должны получать видеофайл как MultipartFileData в ASP .NET. Ниже приведен код ASP .Net для этого. А класс CustomMultipartFormDataStreamProvider помогает сохранить имя видеофайла как есть.
public class UploadController : ApiController
{
[HttpPost]
public async Task<HttpResponseMessage> PostUpload()
{
// Check whether the POST operation is MultiPart?
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
// Prepare CustomMultipartFormDataStreamProvider in which our multipart form
// data will be loaded.
string fileSaveLocation = HttpContext.Current.Server.MapPath("~/App_Data");
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
List<string> files = new List<string>();
try
{
// Read all contents of multipart message into CustomMultipartFormDataStreamProvider.
await Request.Content.ReadAsMultipartAsync(provider);
foreach (MultipartFileData file in provider.FileData)
{
files.Add(Path.GetFileName(file.LocalFileName));
}
// Send OK Response along with saved file names to the client.
return Request.CreateResponse(HttpStatusCode.OK, files);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
// We implement MultipartFormDataStreamProvider to override the filename of File which
// will be stored on server, or else the default name will be of the format like Body-
// Part_{GUID}. In the following implementation we simply get the FileName from
// ContentDisposition Header of the Request Body.
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider {
public CustomMultipartFormDataStreamProvider(string path) : base(path) { }
public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers) {
return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
}
}
ASP .Net code which returns Not Found ServerResponse to android. Где жерех это возвращает? И где вы получаете это в своем приложении для Android?