1

I have tried 2 methods of calling the web api from a Typescript component: XMLHttpRequest and HttpRequest. Both have the exact same effect.

I can reach the web api if I do not send the file as a parameter in the .send() command. Sending the file results in this message in the browser:

enter image description here

Typescript:

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;
  }
}

Web 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";
        }
    }
}

Here is my api Startup code:

 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");

        }
    }

3 Answers 3

0

You need check enable CORS in your web API https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api

And change upload method in TS to

   upload(file: File) {
       const formData: FormData = new FormData();
       formData.append("file", file, file['name']);
       return this.http.post('/api/UploadFile/UploadFile', formData);
    }
Sign up to request clarification or add additional context in comments.

Comments

0

If you enable the CORS correctly, you could use below code to post file to web api

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();

Comments

0

Finally got it to work! I tried all of the suggestions here but none were working for me. I reverted back to using XMLHttpRequest. All I had to do was remove the "setRequestHeader" line and voila - everything worked.

Here is the typescript:

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;
  }

Here is the Controller in web 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();
        }


    }

Here is the startup.cs in web 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.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");

        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.