J'ai un serveur principal asp.net (utilisant .net core 2.2) qui a FileUploadController qui écoute la demande de publication de fichier entrant.
@Injectable() export class JwtInterceptor implements HttpInterceptor { intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // add authorization header with jwt token if available // if (request.url.indexOf('/upload')) { // return next.handle(request); // } const token = localStorage.getItem('token'); const currentUser = JSON.parse(localStorage.getItem('user')); if (currentUser && token) { request = request.clone({ setHeaders: { Authorization: `Bearer ${token}`, // 'Content-Type': 'application/json' <---- Main Problem. } }); } return next.handle(request).pipe(catchError(err => this.handleError(err))); } }
J'ai créé une application angulaire (en utilisant la version angulaire 8) qui peut choisir le fichier à télécharger à ClientApplication et j'ai créé trois services de publication qui ont appelé l'api" http: / / localhost: 5000 / api / fileupload / upload ".
Post Angular HttpClient standard. lorsque le serveur lit, IFormFile est nul.
const formData: FormData = new FormData(); formData.append('file', file, file.name); const req = new HttpRequest('POST', this.endpoint, formData); return this.http.request(req);
Ajout de HttpHeaders, j'essaie des en-têtes vides, undefined et d'autres solutions proposées par stackoverflow et google.
const header = new HttpHeaders() //1 header.append('enctype', 'multipart/form-data'); //2 header.append('Content-Type', 'multipart/form-data'); //3
Si je mets httpheader avec des ressources en requête, le serveur donne 415 (type de média non pris en charge)
J'essaye HttpRequest de '@ angular / common / http' qui me donne finalement le résultat que je veux.
const formData: FormData = new FormData(); formData.append('file', file, file.name); // return this.http.post(this.endpoint, file); return this.http.post(this.endpoint, formData); // Problem solved
Je veux savoir est-ce un bug ou mon malentendu? Si vous consultez le didacticiel en ligne, la plupart des développeurs utilisent "this.HttpClient.post". D'après ce que j'ai lu, je peux utiliser httpclient.post et le cadre angulaire définira automatiquement l'en-tête approprié pour l'utilisateur. Il semble que cela ne fonctionne pas.
Après une enquête approfondie, la première erreur est mon erreur d'utiliser le fichier au lieu de formData, la deuxième erreur est l'en-tête "content-type" déclaré dans httpinterceptor qui après avoir été supprimé, il charge le fichier comme prévu.
[HttpPost("Upload")] // public async Task<IActionResult> Upload([FromForm(Name="file")]IFormFile file) { // public async Task<IActionResult> Upload([FromForm]IFormFile file) { public async Task<IActionResult> Upload(IFormFile file) { Console.WriteLine("***" + file); if(file == null) return BadRequest("NULL FILE"); if(file.Length == 0) return BadRequest("Empty File"); Console.WriteLine("***" + host.WebRootPath); if (string.IsNullOrWhiteSpace(host.WebRootPath)) { host.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"); } var uploadsFolderPath = Path.Combine(host.WebRootPath, "uploads"); if (!Directory.Exists(uploadsFolderPath)) Directory.CreateDirectory(uploadsFolderPath); var fileName = "Master" + Path.GetExtension(file.FileName); var filePath = Path.Combine(uploadsFolderPath, fileName); using (var stream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(stream); } return Ok("Okay"); }
Serveur: " https://github.com/ phonemyatt / TestPlaygroundServer "
3 Réponses :
Le code ci-dessous fonctionne pour vous
[HttpPost("UploadSecond")] [DisableRequestSizeLimit] public async Task<IActionResult> UploadSecond([FromForm]IFormFile file)
Puis dans votre contrôleur
uploadSecond(file: File) { const formData: FormData = new FormData(); formData.append('file', file, file.name); return this.http.post('https://localhost:44393/api/fileupload/UploadSecond', formData); }
Après avoir changé cela, j'ai eu cette erreur. System.IO.InvalidDataException: limite de type de contenu manquante
Essayez de supprimer les httpOptions comme celles-ci return this.http.post (url, formData);
pour voir si cela fonctionne ou non
Il peut atteindre mon api de téléchargement mais le fichier est toujours nul.
fichier reçu toujours nul. est-ce un bug angulaire?
Avez-vous déjà essayé avec le fichier IFormFile [FromForm] et le fichier IFormFile?
oui, j'essaye avec [FromFile (Name = "file")], [FromFile] et sans [FromFile].
continuons cette discussion dans le chat .
Dans votre premier exemple qui ne fonctionne pas, vous passez file
dans post (...)
au lieu de formData
. Il devrait être:
const formData: FormData = new FormData(); formData.append('file', file, file.name); return this.http.post(this.endpoint, formData);
Le code que vous affichez pour le contrôleur semble être correct, donc ce devrait être le seul changement requis. Vous n'avez pas besoin de définir des en-têtes personnalisés sur la demande envoyée par Angular.
Si vous utilisez FormData dans le client, vous pouvez obtenir des fichiers comme celui-ci.
[HttpPost("Upload"), DisableRequestSizeLimit] public ActionResult Upload() { try { var file = Request.Form.Files[0]; var folderName = Path.Combine("Resources","Images"); var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName); if (file.Length > 0) { var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"'); var fullPath = Path.Combine(pathToSave, fileName); var dbPath = Path.Combine(folderName, fileName); using (var stream = new FileStream(fullPath, FileMode.Create)) { file.CopyTo(stream); } return Ok(new { dbPath }); } else { return BadRequest(); } } catch (Exception ex) { return StatusCode(500, "Internal server error"); } }
Essayez ceci:
public async Task Upload ([FromForm] IFormFile file) {}
@PrashantPimpale J'ai essayé avec l'attribut FromForm, je ne peux toujours pas le télécharger