Click here to Skip to main content
15,902,198 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I am trying to upload an image in .NET core, but I it gives me an error while the stream copy to another stream to save the data. When it runs as local server, it works perfectly and I upload all execution files to Linux (Ubuntu) server, then the following error has displayed on the console window. Actually I am creating an API for my mobile app. Everything works fine so far except this uploading an image part in linux. Server location is in India. Thank you.

Quote:
Unhandled exception. System.ObjectDisposedException: Safe handle has been closed.
Object name: 'SafeHandle'.
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at Interop.Sys.PRead(SafeHandle fd, Byte* buffer, Int32 bufferSize, Int64 fileOffset)
at System.IO.RandomAccess.ReadAtOffset(SafeFileHandle handle, Span`1 buffer, Int64
fileOffset)
at
Microsoft.Win32.SafeHandles.SafeFileHandle.ThreadPoolValueTaskSource.ExecuteInternal()
--- End of stack trace from previous location ---
at Microsoft.Win32.SafeHandles.SafeFileHandle.ThreadPoolValueTaskSource.GetResult(Int16
token)
at
Microsoft.Win32.SafeHandles.SafeFileHandle.
ThreadPoolValueTaskSource.System.Threading.Tasks.
Sources.IValueTaskSource<system.int32>.GetResult(Int16 token)
at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.ReadAsync(Memory`1 buffer,
CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.ReferenceReadStream.ReadAsync(Memory`1 buffer,
CancellationToken cancellationToken)
at System.IO.Stream.<copytoasync>g__Core|29_0(Stream source, Stream destination, Int32
bufferSize, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.FormFile.CopyToAsync(Stream target, CancellationToken
cancellationToken)
at ContractAPI.Helper.AppBaseService.CreateFile(String savePath, IFormFile formFile) in
AppBaseService.cs:line 38
at System.Threading.Tasks.Task.<>c.<throwasync>b__128_1(Object state)
at System.Threading.QueueUserWorkItemCallback.<>c.
<.cctor>b__6_0(QueueUserWorkItemCallback quwi)
at System.Threading.QueueUserWorkItemCallback.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()


What I have tried:

C#
<pre lang="C#">

  public class Program
 {
      public static void Main(string[] args)
      {
         CreateHostBuilder(args).Build().Run();
      }   
       
      public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            }); 
 }  


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

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
       services.AddDbContext<ContractMakerContext>(options =>
       {
           options.UseMySQL(Configuration.GetConnectionString("Default"));
       });

       services.AddScoped<ICompanyInfoService, CompanyInfoService>();
       services.AddControllers();
    }
    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger();
            app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ContractAPI v1"));
        }
         
        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseStaticFiles();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
 }

 public interface ICompanyInfoService
 {
    Task<ResponseUserCompanyInfo> updateUserCompanyInfoWithFile(CompanyInfoWithFile info);
 }

 public class CompanyInfoService : ICompanyInfoService
 {

      public static IWebHostEnvironment _environment;
        public CompanyInfoService(IWebHostEnvironment environment)
        {
            _environment = environment;
        }

     public async Task<ResponseUserCompanyInfo> updateUserCompanyInfoWithFile(CompanyInfoWithFile info)
     {
         ResponseUserCompanyInfo response = new ResponseUserCompanyInfo();
         

         CreateFile($"{_environment.WebRootPath}{Constants.SaveCompanyImagePath}", info.company_logo_url); 
         return response;
     }
     
     private async void CreateFile(string savePath, IFormFile formFile)
    {
        if (!Directory.Exists(savePath))
        {
            Directory.CreateDirectory(savePath);
        }

        if (formFile.Length <= 0) return;

        using (var filestream = File.Create($"{savePath}{formFile.FileName}"))
        {
             await formFile.CopyToAsync(filestream); //Problem is here
        }
    }
 } 


[Route("api/[controller]")]
[ApiController]
public class CompanyInfoController : ControllerBase
{
   ICompanyInfoService _service;
   public CompanyInfoController(ICompanyInfoService service)
   {
       _service = service;
   }

   [HttpPost("updateUserCompanyInfoWithFile")]
    public async Task<IActionResult> updateUserCompanyInfoWithFile([FromForm] CompanyInfoWithFile info)
    { 
        ResponseUserCompanyInfo response = await Service.updateUserCompanyInfoWithFile(info);
        return MakeResponse(response, response.error_code);
    }
}
Posted
Updated 5-Mar-23 0:11am
v3

1 solution

Yes, You are using async void which is fire and forget. This means that you are not waiting for the asynchronous operation to finish.

Change:
C#
private async void CreateFile(string savePath, IFormFile formFile)

TO:
C#
private async Task CreateFile(string savePath, IFormFile formFile)

Then change:
C#
CreateFile($"{_environment.WebRootPath}{Constants.SaveCompanyImagePath}", info.company_logo_url);

TO:
C#
await CreateFile($"{_environment.WebRootPath}{Constants.SaveCompanyImagePath}", info.company_logo_url);


Now the code will wait for the asynchronous operation to finish.
 
Share this answer
 
Comments
Member 14526095 5-Mar-23 19:49pm    
Thank you thank you so much sir. I solved the problem and I did as you said. Appreciated.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900