c# - Angular 8'den Asp.net Core 2.2'ye Dosya Yükleme Yapılamıyor
Elimde, gelen dosya için post isteğini dinleyen FileUploadController'a sahip olan asp.net core sunucusu (.net core 2.2 kullanıyor) var.
[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");
}
Angular sürüm 8 kullanarak client uygulamasında yüklemek için dosya seçebilen bir Angular uygulaması oluşturdum ve "http://localhost:5000/api/fileupload/upload" API'sine çağrı yapan üç post servisi oluşturdum.
Standart Angular HttpClient Postu. Sunucu okuduğunda, IFormFile null.
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
HttpHeaders eklendi, boş başlıkları, tanımsızları ve StackOverflow ile Google'dan önerilen diğer çözümleri deniyorum.
const header = new HttpHeaders() //1 header.append('enctype', 'multipart/form-data'); //2 header.append('Content-Type', 'multipart/form-data'); //3
Eğer isteğe kaynaklarla birlikte httpheader koyarsam, sunucu 415 (desteklenmeyen medya türü) verir
'@angular/common/http'ten HttpRequest'i deniyorum ve sonunda istediğim sonucu veriyor.
const formData: FormData = new FormData(); formData.append('file', file, file.name); const req = new HttpRequest('POST', this.endpoint, formData); return this.http.request(req);
Bunun bir hata mı yoksa benim yanlış anlamam mı olduğunu bilmek istiyorum? Çevrimiçi eğitimleri kontrol ederseniz, çoğu geliştirici "this.HttpClient.post" kullanıyor. Okuduklarıma göre, httpclient.post kullanabilirim ve Angular framework kullanıcının uygun başlığını otomatik olarak ayarlayacaktır. Görünüşe göre bu işi yapmıyor.
Kapsamlı bir araştırmadan sonra, ilk hata dosya yerine formData kullanmamdan kaynaklanıyor, ikinci hata ise httpinterceptor içinde bildirilen "content-type" başlığıdır; bu kaldırıldıktan sonra dosya beklendiği gibi yükleniyor.
@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)));
}
}
Sunucu: "https://github.com/phonemyatt/TestPlaygroundServer"
Müşteri: "https://github.com/phonemyatt/TestPlayground"
Cevap #1
İlk örneğinizde, bu işe yaramıyor, formData yerine file'ı post(...)'a geçiriyorsunuz. Şu şekilde olmalı:
const formData: FormData = new FormData();
formData.append('file', file, file.name);
return this.http.post(this.endpoint, formData);
Kontrolcü için gösterdiğiniz kod doğru görünüyor, bu yüzden gereken tek değişiklik bu olmalı. Angular'dan gönderilen isteğe herhangi bir özel başlık eklemenize gerek yok.
Cevap #2
Aşağıdaki kod senin için çalışır
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);
}
O zaman kontrolcünüzde
[HttpPost("UploadSecond")]
[DisableRequestSizeLimit]
public async Task<IActionResult> UploadSecond([FromForm]IFormFile file)

