#api #file-upload #microsoft-graph-api #onedrive #microsoft-graph-sdks
#API #загрузка файла #microsoft-graph-api #onedrive #microsoft-graph-sdks
Вопрос:
Я пытаюсь загрузить большой файл на один диск с помощью Microsoft Graph API. Загрузка на один диск работает нормально, но файл поврежден. Пожалуйста, помогите мне решить проблему.
public ActionResult UploadLargeFiles(string id, [FromForm]IFormFile files)
{
string fileName = files.FileName;
int fileSize = Convert.ToInt32(files.Length);
var uploadProvider = new JObject();
var res = new JArray();
var isExistence = _mailService.GetUploadFolder(id);
if (isExistence != HttpStatusCode.OK)
{
var createFolder = _mailService.CreateUploadFolder(id);
if (createFolder != HttpStatusCode.Created)
{
return BadRequest(ModelState);
}
}
if (files.Length > 0)
{
var uploadSessionUrl = _mailService.CreateUploadSession(id, fileName);
if (uploadSessionUrl != null)
{
if (fileSize < 4194304)
{
uploadProvider = _mailService.UploadByteFile(id, uploadSessionUrl, files);
res.Add(uploadProvider);
}
}
else
{
return BadRequest(ModelState);
}
}
return Ok();
}
-
createUploadSession
public string CreateUploadSession(string upn, string fileName) { var uploadSession = _mailGraphService.CreateUploadSession(upn, fileName).Resu< var sessionResult = new UploadSessionDTO(uploadSession); return sessionResult.uploadUrl; } public async Task<UploadSessionDTO> CreateUploadSession(string upn, string fileName) { this.InitHttpClient(); var jObject = JObject.FromObject(new { item = new Dictionary<string, object> { { "@microsoft.graph.conflictBehavior", "rename" } }, fileSystemInfo = new Dictionary<string, object> { { "@odata.type", "microsoft.graph.fileSystemInfo" } }, name = fileName }); var toJson = JsonConvert.SerializeObject(jObject); var content = new StringContent(toJson, Encoding.UTF8, "application/json"); var response = await _client.PostAsync("users/" upn "/drive/root:/MailFiles/" fileName ":/createUploadSession", content); if (!response.IsSuccessStatusCode) return null; var strData = await response.Content.ReadAsStringAsync(); dynamic uploadSession = JsonConvert.DeserializeObject<UploadSessionDTO>(strData); return uploadSession; } public JObject LargeFileUpload(string upn, string url, IFormFile files) { var responseCode = HttpStatusCode.OK; var jObject = new JObject(); int idx = 0; int fileSize = Convert.ToInt32(files.Length); int fragSize = 4 * 1024 * 1024; //4MB => 4 * 1024 * 1024; var byteRemaining = fileSize; var numFragments = (byteRemaining / fragSize) 1; while (idx < numFragments) { var chunkSize = fragSize; var start = idx * fragSize; var end = idx * fragSize chunkSize - 1; var offset = idx * fragSize; if (byteRemaining < chunkSize) { chunkSize = byteRemaining; end = fileSize - 1; } var contentRange = " bytes " start "-" end "/" fileSize; byte[] file = new byte[chunkSize]; using (var client = new HttpClient()) { var content = new ByteArrayContent(file); content.Headers.Add("Content-Length", chunkSize.ToString()); content.Headers.Add("Content-Range", contentRange); var response = client.PutAsync(url, content); var strData = response.Result.Content.ReadAsStringAsync().Resu< responseCode = response.Result.StatusCode; //업로드 성공 if (responseCode == HttpStatusCode.Created) { JObject data = JObject.Parse(strData); string downloadUrl = data["@content.downloadUrl"].ToString(); string itemId = data["id"].ToString(); //파일 크기 -> kb로 변환 fileSize = fileSize / 1000; jObject = JObject.FromObject(new { name = files.Name, id = itemId, url = downloadUrl, size = (double)fileSize }); } //업로드 충돌 else if (responseCode == HttpStatusCode.Conflict) { var restart = RestartByteFile(upn, url, files.Name); responseCode = restart; } } byteRemaining = byteRemaining - chunkSize; idx ; } if (responseCode == HttpStatusCode.Created) { return jObject; } else return jObject = JObject.FromObject(new { result = "실패" }); }
Когда я проверил OneDrive, файл был загружен нормально, а когда я загрузил и открыл файл, он оказался поврежденным файлом.
Интересно, почему файл повреждается при загрузке и как это исправить. Если проблема не может быть решена, пожалуйста, сообщите нам, что она не может быть решена.
Комментарии:
1. (1) Вы пытались вручную загрузить файл в onedrive, и у вас все еще работает? (2) Помимо вашего кода, вы пытались загрузить файл с помощью MS Graph Explorer или POSTMAN? Работает ли это для вас?
2. @Dev (1) При загрузке вручную файл загружается нормально. (2) Работает снаружи.
3. Если он работает снаружи, то это не проблема с вызовом Graph API, но я подозреваю, что это может быть связано с приведенным выше кодом / логикой или проверкой правильности установки / передачи необходимых заголовков, правильного размера вложений — аналогично тому, что вы делаете с POSTMAN / MS Graph Explorer. Дайте мне знать, как это происходит.
4. @Dev (1) Размер вложенного файла не имеет значения. Загружаются и повреждаются даже маленькие и большие файлы. (2) Как мне передать файл, преобразованный в байты, в качестве заголовка при передаче с использованием Postman или MS Graph API? В коде я могу преобразовать его и сразу передать, но как мне преобразовать его в байты случайным образом и вызвать его из graph API? (3) При методе прямой передачи без создания сеанса загрузки файл загружается, но он поврежден. В этом случае возникает ошибка в части преобразования файла в байты?
5. Когда я попытался повторить проблему, я не смог увидеть ваше поведение. При этом я помню связанную с этим тему. Посмотрите, что вы знаете об этом, и попробуйте доступный в нем пример кода, чтобы узнать, поможет ли он вам продвинуться вперед — github.com/microsoftgraph/msgraph-sdk-dotnet/issues/493