Cannot access a disposed object while using different contexts - c#

I am trapped with definitions of Entity framework and using objects.
I am trying to save an uploaded file once I am saving the details related to that file in my database.
public async Task<IActionResult> Edit(string List<IFormFile> files, [Bind("param")] Entity entity)
{
if (ModelState.IsValid)
{
try
{
_context.Update(entity);
await _context.SaveChangesAsync();
//update Attachments
if (files.Count > 0)
{
attachment.UploadFiles(files);
}
}
catch (DbUpdateConcurrencyException)
{
if (!EntityExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction("Index");
}
return View(entity);
}
When I run the application and want to submit the form I receive below error:
Cannot access a disposed object.
Object name: 'FileBufferingReadStream'.
[HttpPost]
public async void UploadFiles(List<IFormFile> files)
{
if (files == null || files.Count == 0)
{
log.error("files not selected");
}
try
{
List<string> filenames = new List<string>();
string directory = Directory.GetCurrentDirectory() + "\\wwwroot";
createDir(directory);
foreach (var file in files)
{
string filename = file.GetFilename();
filenames.Add(filename);
}
if (filenames.Count > 0)
foreach (var filename in filenames)
{
AttachmentQ(filename, directory, createdBy);
}
foreach (var file in files)
{
string filename = file.GetFilename();
var path = Path.Combine(directory, filename);
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
filenames.Add(filename);
}
}
catch (Exception e)
{
log.error(e.Message);
}
}
[ValidateAntiForgeryToken]
public async void AttachmentQ(string filename, string path, string createdBy)
{
try
{
Attachment attachment = new Attachment
{
Name = filename,
Path = path,
CreatedBy = createdBy,
CreatedDate = DateTime.Now
};
_context.Add(attachment);
await _context.SaveChangesAsync();
}
catch (Exception e)
{
log.error(e.Message);
}
}
Surprisingly I don't get error in debug mode. But when I run the app I get This page isn’t working error.
I also noticed I need to return a value when I use async but I don't have any return vale in UploadFiles() and AttachmentQ() methods.
Could you please help me how to handle objects when using different contexts. Thanks

Do NOT use async void at all.
if you want to use async/await pattern then let your methods returns Task
public async Task UploadFiles(List<IFormFile> files)

Related

Passing and calling a function from one service to the another

I wrote a function that will get and update what I need.
public async Task<bool> UpdateWellFile(IEnumerable<AttachedFileListView> files, string wellId)
{
var updateFiles = await _attachedFileRepo.GetAllQueryable().Where(af => af.WellId == wellId).ToListAsync();
if (files == null)
{
throw new ServiceException("File Not Found.");
}
foreach(var file in files)
{
var updateFile = updateFiles.SingleOrDefault(af => af.Id == file.Id);
updateFile.Category = file.Category;
_attachedFileRepo.Update(updateFile);
}
await _attachedFileRepo.CommitAsync();
return true;
}
This is in my AttachedFile Interface
public interface IAttachedFileService
{
Task<IEnumerable<AttachedFileListView>> GetWellAttachedFiles(string wellId);
Task<string> SaveFile(IFormFile file, string wellId, string userId);
Task<IEnumerable<string>> SaveFiles (IEnumerable<IFormFile> files, string wellId, string userId);
Task<bool> UpdateWellFile(IEnumerable<AttachedFileListView> files, string wellId);
Task<AttachedFile> GetFile(string fileId);
Task<string> DeleteFile(string fileId);
}
Now I need to pass this updateWellFile function into the WellService and call it so I added it to the service but it is throwing this error
here is the well service and I added the "accountservice" so I am not sure what else it needs

getting file already exist error as code running async

As below code runs async, 2 zip created with same name and when trying to copy destination, getting error saying that,
The file 'C:\Temp\test_20181024032123496.Zip' already exists.
How to skip this condition? Thanks!
private static async Task<bool> GenerateZipFile(FileSystemInfo file1, string zipFilePath)
{
try
{
using (var zip = ZipFile.Open($"{zipFilePath}\\test_{DateTime.UtcNow:yyyyMMddHHmmssfff}.Zip", ZipArchiveMode.Create))
{
zip.CreateEntryFromFile(file1.FullName, file1.Name, CompressionLevel.Optimal);
}
}
catch (Exception ex)
{
Console.Write(ex);
}
}
Ok, so I'm not sure if you have the problem with the zip file you're creating or with the file you're adding into the zip file so I'm adding code that checks if either of them exists
private static async Task<bool> GenerateZipFile(FileSystemInfo file1, string zipFilePath)
{
try
{
string newZipFilePath = $"{zipFilePath}\\test_{DateTime.UtcNow:yyyyMMddHHmmssfff}.Zip"
if (!System.IO.File.Exists(newZipFilePath))
{
using (var zip = ZipFile.Open(newZipFilePath, ZipArchiveMode.Create))
{
if(System.IO.File.Exists(file1.FullName))
{
zip.CreateEntryFromFile(file1.FullName, file1.Name, CompressionLevel.Optimal);
}
}
}
}
catch (Exception ex)
{
Console.Write(ex);
}
}
This should work, but you should also check which is the one you actually need and only use that one

Exception while creating SQLite database

I develop a Universal app that use a local SQLite database. As I need to know the database version, I store an additional information that contains this information.
At the application startup, I check if the database exists, and if the database version has changed.
public sealed partial class App : Application
{
// DB Name
public static string DBFileName = "myDb.sqlite";
public static string DBpath;
// DB Version
public static string DBVersionFilename = "myDb.version";
public static string DBVersionPath;
public static string DBVersion = "1.1.0";
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
ManageDB();
}
private async Task ManageDB()
{
if (!CheckDbExist().Result)
{
CreateDb();
}
else
{
if (CheckDbVersionUpdated().Result)
{
await DeleteDb();
CreateDb();
}
}
}
private async Task<bool> CheckDbExist()
{
try
{
StorageFile storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync(DBFileName);
DBpath = storageFile.Path;
return true;
}
catch { }
return false;
}
private void CreateDb()
{
try
{
StorageFile storageFile = ApplicationData.Current.LocalFolder.CreateFileAsync(DBFileName, CreationCollisionOption.OpenIfExists).GetResults();
DBpath = storageFile.Path;
var dbconnection = new SQLiteAsyncConnection(DBpath, false);
dbconnection.CreateTableAsync<Article>();
//...
StorageFile file = ApplicationData.Current.LocalFolder.CreateFileAsync(DBVersionFilename, CreationCollisionOption.ReplaceExisting).GetResults();
FileIO.WriteTextAsync(file, DBVersion);
}
catch (Exception e)
{ }
}
private async Task<bool> DeleteDb()
{
try
{
StorageFile storageFile = ApplicationData.Current.LocalFolder.CreateFileAsync(DBFileName, CreationCollisionOption.OpenIfExists).GetResults();
await storageFile.DeleteAsync(StorageDeleteOption.PermanentDelete);
return true;
}
catch { }
return false;
}
private async Task<bool> CheckDbVersionUpdated()
{
try
{
string userDBVersion;
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(DBVersionFilename);
userDBVersion = await FileIO.ReadTextAsync(file);
if (userDBVersion != DBVersion)
return true;
else
return false;
}
catch { }
return false;
}
}
There is a problem on CreateDB():
if I browse this code step by step, with breakpoint, there is no problem
but if I don't place breakpoint I meet an exception after calling var dbconnection = new SQLiteAsyncConnection(DBpath, false);:
System.InvalidOperationException: A method was called at an unexpected time.
A method was called at an unexpected time.
at Windows.Foundation.IAsyncOperation`1.GetResults()
at TestRating.App.CreateDb()}
Would you have an idea about the encountered problem? Is there another way to do this?
When I remove ".Results()" it seems that the "CreateDb()" function works correctly:
private async Task<bool> CreateDb()
{
try
{
StorageFile storageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(DBFileName, CreationCollisionOption.OpenIfExists);
DBpath = storageFile.Path;
var dbconnection = new SQLiteAsyncConnection(DBpath, false);
dbconnection.CreateTableAsync<Article>();
//...
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(DBVersionFilename, CreationCollisionOption.ReplaceExisting);
FileIO.WriteTextAsync(file, DBVersion);
return true;
}
catch (Exception e)
{ }
return false;
}
Do you have an explanation?

c# winrt delete file

When I delete file like this behind, it throws an exception:
Value does not fall within the expected range.
when deleteasync.
public static async Task DeleteFile(string fileName, string folderPath)
{
try
{
StorageFolder sf = await CheckFolder(folderPath);
StorageFile sfile = await sf.GetFileAsync(fileName);
if (sfile != null)
{
await sfile.DeleteAsync();
}
}
catch (Exception)
{
}
}

checking to see if Stream inputStream File exists or not

I am changing a method that used to accept string for temp folder and string for file and changing it to a stream and i wanted some help how to check if file exists or not.
bool UploadFile(Stream inputStream, Stream inputFile);
This is what i originally had and i want to change so the parameters accepts a stream
bool UploadFile(string tempFolder, string fileName)
public bool UploadFile(string tempFolder, string fileName)
{
if (File.Exists(fileName))
{
testingUsage.Upload(tempFolder, fileName);
return testingUsage.Exists(tempFolder);
}
return false;
}
do i create two streams one for the file and one for location?
Assuming this is your Upload Action:
[HttpPost]
public ActionResult Upload()
{
try
{
if (Request.Files.Count > 0)
{
string tempFolder = "...";
var file = Request.Files[0];
if(UploadFile(tempFolder, file))
{
// Return a View to show a message that file was successfully uploaded...
return View();
}
}
}
catch (Exception e)
{
// Handle the exception here...
}
}
Your Method can be something like this:
private bool UploadFile(string tempFolder, HttpPostedFileBase file)
{
var path = Path.Combine(tempFolder, file.FileName);
// if the file does not exist, save it.
if (!File.Exists(path))
{
file.SaveAs(path);
return true;
}
return false;
}

Categories

Resources