Загрузка файла из Typescript в веб-интерфейс asp.net-core: невозможно передать файл в качестве параметра веб-API - PullRequest
0 голосов
/ 25 июня 2019

Я пробовал 2 способа вызова веб-API из компонента Typescript: XMLHttpRequest и HttpRequest.Оба имеют одинаковый эффект.

Я могу получить доступ к веб-API, если не отправлю файл в качестве параметра в команде .send ().Отправка файла приводит к этому сообщению в браузере:

enter image description here

Машинопись:

note: environment.fileUploadX_Url is "https://localhost:44387/api/UploadFile/UploadFile"

   export class FileService {

  private url = environment.fileUploadX_Url;// + environment.fileUploadLoc;

  constructor(private http: HttpClient) {
  }

  upload(file: File) {

    var xhr = this.createCORSRequest('POST', this.url);
    xhr.upload.onprogress = function (event) {
      console.log('Uploaded ${event.loaded} of ${event.total}');
    };

    const fd = new FormData();
    fd.append('resultFile', file);

    xhr.send(fd);//

    //const req = new HttpRequest('POST', this.url, fd);
    //req.headers.append('Access-Control-Allow-Origin', environment.serverUrl);
    //this.http.request(req).subscribe(result => { });    

  }

  createCORSRequest(method, url) {
    var xhr = new XMLHttpRequest();
      xhr.withCredentials = false;

    xhr.open(method, url, true);
    xhr.setRequestHeader("Content-Type", "multipart/form-data;");

    return xhr;
  }
}

Веб-API:

namespace Namespace.Controllers
{
    [EnableCors("ThePolicy")]
    [Route("api/[controller]")]    
    [ApiController]
    public class UploadFileController : ControllerBase
    {
        [EnableCors("ThePolicy")]
        [HttpPost, DisableRequestSizeLimit, Route("UploadFile")]
        public async Task UploadFile()
        {
            var files = Request.Form.Files;
            HttpResponseMessage res = new HttpResponseMessage();
            var filePath = "/Logs";
        }
    }
}

Вот мой API-код запуска:

 public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddCors(o => o.AddPolicy("ThePolicy", builder =>
           {
               builder.AllowAnyOrigin()
               .AllowAnyMethod()
               .AllowAnyHeader();
           }));


            ConfigureServicesModule<DB_Dev_Phase2Context>.Register(services, Configuration);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            //app.UseHttpsRedirection();
            //app.UseMvc();
            ConfigureModule.Configure(app, env, Configuration);
            app.UseCors("ThePolicy");

        }
    }

Ответы [ 4 ]

0 голосов
/ 28 июня 2019

Наконец-то получил его на работу! Я попробовал все предложения здесь, но ни один не работал для меня. Я вернулся к использованию XMLHttpRequest. Все, что мне нужно было сделать, это удалить строку setRequestHeader и вуаля - все заработало.

Вот машинопись:

export class FileService {
  _message: string;
  private url = environment.fileUploadX_Url;//this.config.FILEUPLOAD_ENDPOINT;//
  @Output('fileLoad') fileLoaded: EventEmitter<string> = new EventEmitter<string>();

  constructor(private http: HttpClient, private config: ConfigService) {
  }

  upload(file: File): void {

    var xhr = this.createCORSRequest('POST', this.url);

    const fd = new FormData();
    fd.append('file', file);

    xhr.send(fd);

  }

  createCORSRequest(method, url) {
    var xhr = new XMLHttpRequest();
    xhr.withCredentials = false;
    xhr.addEventListener('loadend', this.handleLoadEnd.bind(this));
    xhr.addEventListener('error', this.handleLoadEnd);
    xhr.open(method, url, true);


   // xhr.setRequestHeader("Content-Type", "multipart/form-data");

    return xhr;
  }

Вот контроллер в веб-API:

 [Produces("application/json")]
    [Route("api/[controller]")]    
    [ApiController]
    public class UploadFileController : ControllerBase
    {           
        [DisableRequestSizeLimit]
        [HttpPost("UploadFile")]      
        public async Task<ActionResult> UploadFile()
        {
            try
            {                                
                var file = Request.Form.Files[0];
                string fileName = file.FileName;
                var filePath = Path.Combine("/Logs", fileName);

                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }
            }
            catch (Exception ex) {
                return BadRequest("Unable to upload the file." );
            }

            return  Ok();
        }


    }

Вот файл startup.cs в веб-интерфейсе:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(o => o.AddPolicy("ThePolicy", builder =>
           {
               builder.AllowAnyOrigin()
               .AllowAnyMethod()
               .AllowAnyHeader();
           }));

            //services.AddCors(c =>
            //{
            //    c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
            //});

            ConfigureServicesModule<AviationIQ_Dev_Phase2Context>.Register(services, Configuration);
            services.Configure<FormOptions>(o => {
                o.ValueLengthLimit = int.MaxValue;
                o.MultipartBodyLengthLimit = int.MaxValue;
                o.MemoryBufferThreshold = int.MaxValue;
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            //app.UseHttpsRedirection();
            //app.UseMvc();
            ConfigureModule.Configure(app, env, Configuration);

            app.UseCors("ThePolicy");

        }
    }
0 голосов
/ 25 июня 2019

Вам необходимо проверить включение CORS в вашем веб-API https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api

и изменить способ загрузки в TS на

   upload(file: File) {
       const formData: FormData = new FormData();
       formData.append("file", file, file['name']);
       return this.http.post('/api/UploadFile/UploadFile', formData);
    }
0 голосов
/ 26 июня 2019

Если вы правильно включили CORS, вы можете использовать приведенный ниже код для публикации файла в веб-интерфейсе

upload(file: File):void{      
  const formData: FormData = new FormData();     
  formData.append('image', file, file.name);
  this.http.post(this.url, formData).subscribe(result => {
     console.log(result);
  }, error => console.error(error));
}

startup.cs:

services.AddCors(options =>
        {
            options.AddPolicy("ThePolicy",
            builder =>
            {
                builder.WithOrigins("https://localhost:44323")
                                    .AllowAnyHeader()
                                    .AllowAnyMethod();
            });
        });
//Configure
app.UseCors("ThePolicy");
app.UseHttpsRedirection();
app.UseMvc();
0 голосов
/ 25 июня 2019

Попробуйте удалить Route и добавить Route в HttpPost, как это

    [HttpPost("UploadFile"), DisableRequestSizeLimit]
    public async Task UploadFile()
    {
        var files = Request.Form.Files;
        HttpResponseMessage res = new HttpResponseMessage();
        var filePath = "/Logs";
    }

Также похоже, что ваш CORS-конфиг для ASP.Net Core не работает, попробуйте дважды проверить его. В вашем Startup.cs

app.UseCors(options => options.AllowAnyOrigin());  

services.AddCors(c =>  
{  
   c.AddPolicy("AllowOrigin", options => options => options.AllowAnyOrigin());  
});  

Так в вашем контроллере

[EnableCors("AllowOrigin")]
[Route("api/[controller]")]    
[ApiController]
public class UploadFileController : ControllerBase

, поэтому нет необходимости добавлять EnableCors в ваш метод действия

Вы можете прочитать эту ссылку

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...