Comportamento:
Quando si utilizza l'API per caricare documenti di grandi dimensioni, viene visualizzato il seguente messaggio di errore;
"Exception 413 Request Entity Too Large"
Soluzione:
Fare riferimento alla seguente guida su come caricare file di grandi dimensioni con .NET SDK o REST API;
.NET SDK
Per caricare documenti di grandi dimensioni, è possibile utilizzare il seguente metodo dalle pagine per gli sviluppatori di DocuWare.
Easy Uploading Huge Files | Documentare SDK di DocuWare.
REST API
Per caricare documenti di grandi dimensioni tramite REST API è necessario adottare un approccio diverso.
Si prega di fare riferimento all'esempio di come questo può essere realizzato;
using System.Net;
using RestSharp;
using System.IO;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
public static class ChunkUpload {
public static void RestSharpCallSequence()
{
string orgName = ""; // X in X.DocuWare.cloud
string userName = ""; //nome utente con cui effettuare il login
string password = ""; //password
string fileCabinetID = ""; / ID del file cabinet
string BaseUrl = "https://ORGNAME.docuware.com/DocuWare/Platform";
RestClient client = new RestClient(BaseUrl);
RestRequest request = new RestRequest($"{baseURL}/Conto/Logon", Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Accept", "application/json");
request.AddParameter("Organization", orgName);
request.AddParameter("UserName", userName);
request.AddParameter("Password", password);
request.AddParameter("RememberMe", "true");
RestResponse response = client.Execute(request);
//Cattura il cookie per utilizzarlo nella chiamata successiva
Cookie cookie = response.Cookies[1];
Console.WriteLine("Finito");
// Impostazione del chunking
chunkUpload(cookie, client);
}
public static void chunkUpload(Cookie cookie, RestClient restClient)
{
// Definire gli URL dell'API di base e dell'archivio
RestClient client = restClient;
string OrgName = ""; // X in X.DocuWare.cloud
string baseURL = $"https://{OrgName}.docuware.cloud";
string platformURL = $"{baseURL}/DocuWare/Platform";
string FileCabinetId = "98f77e6e-5a56-406e-a6d4-51ef7a37eda1";
// Impostare la dimensione del chunk - 10 MB sono stati impostati arbitrariamente.
int ChunkSize = 10 * 1024 * 1024; // 10 MB
// Impostare il percorso del file da caricare
string filePath = $""; //dovrebbe essere cambiato con il proprio percorso del file|
try
{
//Aprire il file stream e ottenere la dimensione, il nome e la data di modifica del file.
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
long totalFileSize = fileStream.Length;
string fileName = Path.GetFileName(filePath);
DateTime modificationDate = File.GetLastWriteTimeUtc(filePath);
// Impostare l'URL dell'endpoint e creare un nuovo oggetto RestRequest con il metodo POST
string suffix = $"/FileCabinets/{FileCabinetId}/Documents/";
string url = $"{platformURL}/{suffix}";
var request = new RestRequest(url, Method.Post);
// Inizializza le variabili per il caricamento dei chunk
string chunkReference = null;
int bytesUploaded = 0;
// Eseguire il loop del file e caricare i chunk
while (bytesUploaded < totalFileSize)
{
// Leggere un pezzo del file in un buffer
byte[] buffer = new byte[ChunkSize];
int bytesRead = fileStream.Read(buffer, 0, ChunkSize);
// Ridimensiona il buffer se l'ultimo chunk è inferiore alla dimensione del chunk
if (bytesRead < ChunkSize)
{
Array.Resize(ref buffer, bytesRead);
}
// Imposta le intestazioni per la richiesta
request.AddHeader("Content-Type", "application/octet-stream");
request.AddHeader("Content-Length", bytesRead.ToString());
request.AddHeader("Content-Disposition", $"inline; filename=\"{fileName}\"; modificationdate=\"{modificationDate:R}\"");
request.AddHeader("X-File-ModifiedDate", $"{modificationDate:R}");
request.AddHeader("X-File-Name", fileName);
request.AddHeader("X-File-Size", totalFileSize.ToString());
request.AddHeader("Cookie", cookie.ToString());
request.AddHeader("Expect", "100-continue");
// Aggiungere i dati del chunk al corpo della richiesta
request.AddParameter("application/octet-stream", buffer, ParameterType.RequestBody);
// Se questo non è il primo chunk, aggiungere il riferimento al chunk e le intestazioni di posizione alla richiesta
if (!string.IsNullOrEmpty(chunkReference))
{
request.AddQueryParameter("loc", bytesUploaded.ToString());
request.AddQueryParameter("chunkReference", chunkReference);
}
// Impostare l'URL di base e aggiungere il cookie al client
Uri baseUri = new Uri(platformURL);
client.CookieContainer.Add(cookie);
// Eseguire la richiesta di caricamento del chunk
var response = client.Execute(request);
var deserializedJsonResponseBody = JsonConvert.DeserializeObject<IntermediateResponse>(response.Content.ToString());
// Controllare il codice di stato della risposta
if (response.StatusCode != HttpStatusCode.OK)
{
Console.WriteLine($"Codice di stato inatteso: {response.StatusCode}");
Console.WriteLine("Errore: caricamento non riuscito.");
return;
}
Console.WriteLine("Request eseguita");
/* Se ci sono altri chunk da caricare, ottenere l'URL successivo dalla risposta
* e creare un nuovo oggetto RestRequest con il metodo POST per il chunk successivo
*/
if (bytesUploaded + bytesRead < totalFileSize)
{
// Deserializzare il JSON della risposta per ottenere il prossimo URL
url = baseURL + deserializedJsonResponseBody.FileChunk.Links[0].href;
request = new RestRequest(url, Method.Post);
}
else //per l'ultimo chunk, ottenere la risposta finale deserializzata
{
var finalResposne = JsonConvert.DeserializeObject<JSON>(response.Content.ToString());
}
// Aggiornare i byte totali caricati e stampare i progressi
bytesUploaded += bytesRead;
Console.WriteLine($"Caricato {bytesUploaded} / {totalFileSize} bytes");
}
Console.WriteLine("File caricato con successo.");
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
/* Le classi seguenti servono per la deserializzazione completa delle risposte JSON.
* Ciò che viene utilizzato è RootObject->FileChunk->Link->href[0], che cattura il link "successivo".
*/
public class FileChunk
{
public List<Link> Links { get; set; }
public bool Finished { get; set; }
public string LastChunkId { get; set; }
public int BytesWritten { get; set; }
}
public class Link
{
public string rel { get; set; }
public string href { get; set; }
}
public class IntermediateResponse
{
public FileChunk FileChunk { get; set; }
public bool HaveMoreTotalPages { get; set; }
public bool HasTextAnnotation { get; set; }
public bool HasXmlDigitalSignatures { get; set; }
public bool AnnotationsPreview { get; set; }
public int TotalPages { get; set; }
public int Id { get; set; }
public bool LastModifiedSpecified { get; set; }
public bool CreatedAtSpecified { get; set; }
public int FileSize { get; set; }
public int SectionCount { get; set; }
public string IntellixTrust { get; set; }
public string VersionStatus { get; set; }
}
public class Section
{
public List<string> SignatureStatus { get; set; }
public Pages Pages { get; set; }
public Thumbnails Thumbnails { get; set; }
public List<Link> Links { get; set; }
public string Id { get; set; }
public string ContentType { get; set; }
public bool HaveMorePages { get; set; }
public int PageCount { get; set; }
public int FileSize { get; set; }
public string OriginalFileName { get; set; }
public string ContentModified { get; set; }
public bool HasTextAnnotation { get; set; }
public bool AnnotationsPreview { get; set; }
}
public class Pages
{
public List<object> Page { get; set; }
}
public class Miniature
{
public List<object> Page { get; set; }
}
public class JSON
{
public Guid FileCabinetId { get; set; }
public List<Field> Fields { get; set; }
public Flags Flags { get; set; }
public Version Version { get; set; }
public List<Link> Links { get; set; }
public List<Section> Sections { get; set; }
public string ContentType { get; set; }
public FileChunk FileChunk { get; set; }
public bool HaveMoreTotalPages { get; set; }
public bool HasTextAnnotation { get; set; }
public bool HasXmlDigitalSignatures { get; set; }
public bool AnnotationsPreview { get; set; }
public int TotalPages { get; set; }
public int Id { get; set; }
public string Title { get; set; }
public string LastModified { get; set; }
public bool LastModifiedSpecified { get; set; }
public string CreatedAt { get; set; }
public bool CreatedAtSpecified { get; set; }
public int FileSize { get; set; }
public int SectionCount { get; set; }
public string IntellixTrust { get; set; }
public string VersionStatus { get; set; }
}
public class Field
{
public bool SystemField { get; set; }
public string FieldName { get; set; }
public string FieldLabel { get; set; }
public bool IsNull { get; set; }
public bool ReadOnly { get; set; }
public object Item { get; set; }
public string ItemElementName { get; set; }
}
public class Flags
{
public bool IsCold { get; set; }
public bool IsDBRecord { get; set; }
public bool IsCheckedOut { get; set; }
public bool IsCopyRightProtected { get; set; }
public bool IsVoiceAvailable { get; set; }
public bool HasAppendedDocuments { get; set; }
public bool IsProtected { get; set; }
public bool IsDeleted { get; set; }
public bool IsEmail { get; set; }
}
}
KBA applicabile sia alle organizzazioni cloud che a quelle on-premise
Si prega di notare: Questo articolo è una traduzione dall’inglese. Le informazioni contenute in questo articolo si basano sulla/e versione/i originale/i del prodotto in inglese. Potrebbero esserci piccoli errori, come nella grammatica usata nella versione tradotta dei nostri articoli. Sebbene non possiamo garantire la completa esattezza della traduzione, nella maggior parte dei casi troverà che è sufficientemente informativa. In caso di dubbi, torni alla versione inglese di questo articolo.
