ASP.NET Core – So erhalten Sie eine Datei in einer Web-API-Anforderung

 C Programming >> C-Programmierung >  >> Tags >> API
ASP.NET Core – So erhalten Sie eine Datei in einer Web-API-Anforderung

Wenn der Client eine Datei in einer mehrteiligen/Formulardatenanforderung sendet, wird sie in ein IFormFile-Objekt geladen. Diese enthält Dateiinformationen (z. B. den Dateinamen) und stellt den Dateiinhalt als Stream bereit. Auf diese Weise können Sie die Datei speichern oder nach Belieben bearbeiten.

Sie können auf das IFormFile-Objekt über Request.Form.Files zugreifen:

[Route("[controller]")]
[ApiController]
public class FilesController : ControllerBase
{
	[HttpPost]
	public async Task<IActionResult> Post()
	{
		IFormFile file = Request.Form.Files.FirstOrDefault();

		//process file content

		return Ok($"Received file {file.FileName} with size in bytes {file.Length}");
	}
}
Code language: C# (cs)

Oder Sie können einen IFormFile-Parameter hinzufügen (oder ihn als Modelleigenschaft hinzufügen), und er ordnet die Dateiformulardaten dem Parameter nach Namen zu:

[Route("[controller]")]
[ApiController]
public class FilesController : ControllerBase
{
	[HttpPost]
	public async Task<IActionResult> Post(IFormFile file)
	{
		//process file content

		return Ok($"Received file {file.FileName} with size in bytes {file.Length}");
	}
}
Code language: C# (cs)

Hinweis:Stellen Sie sicher, dass der IFormFile-Parametername mit dem Namensattribut der Datei in den Formulardaten übereinstimmt, da er sonst nicht zugeordnet wird und null ist.

Auf Festplatte speichern

IFormFile macht den Dateiinhalt als Stream verfügbar. Sie können dies auf der Festplatte speichern, indem Sie einen FileStream erstellen und den Dateistream darauf kopieren.

Hier ist ein Beispiel für das Speichern der Datei auf der Festplatte:

using System.IO;

[HttpPost]
public async Task<IActionResult> Post(IFormFile file)
{
	if (file.Length <= 0)
		return BadRequest("Empty file");

	//Strip out any path specifiers (ex: /../)
	var originalFileName = Path.GetFileName(file.FileName);

	//Create a unique file path
	var uniqueFileName = Path.GetRandomFileName();
	var uniqueFilePath = Path.Combine(@"C:\temp\", uniqueFileName);

	//Save the file to disk
	using (var stream = System.IO.File.Create(uniqueFilePath))
	{
		await file.CopyToAsync(stream);
	}

	return Ok($"Saved file {originalFileName} with size {file.Length / 1024m:#.00} KB using unique name {uniqueFileName}");
}
Code language: C# (cs)

Hinweis:Der Einfachheit halber wird das Datei-Upload-Verzeichnis (C:\temp\) hartcodiert. Realistischerweise möchten Sie diese Einstellung mit den restlichen Konfigurationsdaten zusammenlegen.

Wenn ich eine Anfrage an dieses sende, speichert es die Datei in einem dedizierten Datei-Upload-Verzeichnis und verwendet einen eindeutigen Dateinamen. Es gibt die Antwort zurück:

Saved file class-hierarchy-diagram.png with size 6.88 KB using unique name hseadpgk.xgfCode language: plaintext (plaintext)

IFormFile als Modelleigenschaft

In vielen Fällen möchten Sie die Datei mit den zugehörigen Daten als Teil eines Modells veröffentlichen. Sie können IFormFile als Modelleigenschaft hinzufügen.

public class Document
{
	public string Title { get; set; }
	public string Version { get; set; }
	public IFormFile File { get; set; }
}
Code language: C# (cs)

Fügen Sie dann das Modell als Parameter hinzu und wenden Sie das Attribut [FromForm] an:

[HttpPost]
public async Task<IActionResult> Post([FromForm]Document document)
{
	//process file 

	return Ok($"Processed document {document.Title} v{document.Version} - {document.File.FileName}");
}
Code language: C# (cs)

Es lädt die Dateidaten in die IFormFile-Eigenschaft und Sie können sie verarbeiten / speichern, wie Sie möchten.

Hinweis:Schließen Sie das Attribut [FromForm] ein, wenn Sie Formulardaten einem Modell zuordnen, andernfalls erhalten Sie eine 415-Medien nicht unterstützt-Antwort.

Dateigrößenbeschränkungen

Größenbeschränkungen für Dateien/Anfragen sind je nach Webserver unterschiedlich. In von Kestrel gehosteten Web-Apps sind die wichtigsten Standardlimits:

  • Anforderungsgrößenbeschränkung von 30 MB.
  • Größenbeschränkung für mehrteilige Formularabschnitte auf 128 MB.

Sie können die Limits für alle Anfragen oder pro Aktion ändern. Ich empfehle, die Limits pro Aktion zu ändern, da Sie wahrscheinlich drastisch unterschiedliche Limits für Aktionen wünschen, die sich mit dem Hochladen von Dateien im Vergleich zu anderen Aktionen befassen.

Hier ist ein Beispiel für die Erhöhung der Größenbeschränkung für Anfragen auf 60 MB:

[HttpPost]
[RequestSizeLimit(bytes: 60_000_000)]
public async Task<IActionResult> Post(IFormFile file)
{
	//process file 

	return Ok();
}
Code language: C# (cs)

Dateien werden als Formulardaten gesendet, daher müssen Sie auch die Größenbeschränkungen für Formulare berücksichtigen. Es verwendet das kleinste anwendbare Limit, um zu bestimmen, ob die Anfrage Limits überschritten hat. Sie können die Größenbeschränkungen für Formulare mit dem Attribut [RequestFormLimits] ändern.

Mehrere Dateien empfangen

Es gibt zwei Möglichkeiten, mehrere Dateien zu empfangen:

  • Fügen Sie für jede Datei einen IFormFile-Parameter hinzu.
  • Verwenden Sie IEnumerable, um mehrere Dateien in einem einzigen Parameter zu empfangen.

Die erste Option ist besser, wenn Sie genau wissen, wie viele Dateien der Client übergeben muss. Die zweite Option ist besser, wenn der Client eine beliebige Anzahl von Dateien senden kann.

Hier ist ein Beispiel für den Empfang mehrerer Dateien:

[HttpPost]
public async Task<IActionResult> Post(IEnumerable<IFormFile> files)
{
	foreach(var file in files)
	{
		//process each file
	}

	return Ok();
}
Code language: C# (cs)

Bei diesem Ansatz muss der Client denselben Namen verwenden für jede Datei, die sie den Formulardaten hinzufügen.