how to Upload a single file in the list - asp.net-mvc

I have a list where I upload a file for each record and send them all together to the controller. The code works correctly, but if I don't upload a file for one of them and an empty record is sent, an error occurs.
[HttpPost]
public async Task<IActionResult> SabtEditTaxParvanedAsync([FromForm]IEnumerable<TaxParvande> taxParvandes)
{
if (taxParvandes == null)
{
return Content("File not selected");
}
foreach (var item in taxParvandes)
{
var path = Path.Combine(_environment.WebRootPath, "ListUpload", item.prosessMastand.FileName);
using (FileStream stream = new FileStream(path, FileMode.Create))
{
await item.prosessMastand.CopyToAsync(stream);
stream.Close();
}
var taxDomainModel = new TaxDomainModel
{
prosessId =item.prosessId,
prosessName = item.prosessName,
state = item.state,
FilePath = path,
};
_context.Add(taxDomainModel);
await _context.SaveChangesAsync();
}
return View();
}

But if I don't upload a file for one of them and an empty record is
sent, an error occurs.
Well, in this scenario, you might encounter null reference exception. To overcome this error you could set item.prosessMastand == null then to continue loop which will skip the error upon empty insertion.
public async Task<IActionResult> SabtEditTaxParvanedAsync([FromForm] IEnumerable<TaxParvande> taxParvandes)
{
if (taxParvandes == null)
{
return Content("File not selected");
}
foreach (var item in taxParvandes)
{
if (item.prosessMastand == null)
{
continue;
}
var path = Path.Combine(_environment.WebRootPath, "ListUpload", item.prosessMastand.FileName);
using (FileStream stream = new FileStream(path, FileMode.Create))
{
await item.prosessMastand.CopyToAsync(stream);
stream.Close();
}
var taxDomainModel = new TaxDomainModel
{
prosessName = item.prosessName,
state = item.state,
filePath = path,
};
_context.Add(taxDomainModel);
await _context.SaveChangesAsync();
}
return RedirectToAction("Index");
}
Output:

Related

.NET CORE 3.1, MVC Async method not updating DB

AI am just moving to ASYNC methods and trying to get my data to update. I can select just find so I know the repository is working.
Action
[HttpPost]
public async Task<IActionResult> EditTeam(EmployeeVm empVm)
{
if (!ModelState.IsValid)
{
ModelState.AddModelError("", _errorUpdateMsg);
}
else
{
if (await _teamRepository.UpdateEmployee(empVm.Employee))
{
return RedirectToAction("Index");
}
ModelState.AddModelError("", _errorUpdateMsg);
}
return View(empVm);
}
My Constructor in repo
public TeamRepository(EnvisionDbContext envisionDbContext)
{
_envisonDbContext = envisionDbContext;
}
Here is my Update that does not save
public async Task<bool> UpdateEmployee(Employee employee)
{
var result = await _envisonDbContext.Employees.FirstOrDefaultAsync<Employee>(e => e.Id == employee.Id);
if (result != null)
{
result.FirstName = employee.FirstName;
result.LastName = employee.LastName;
result.Phone = employee.Phone;
result.IsActive = employee.IsActive;
await _envisonDbContext.SaveChangesAsync();
return true;
}
return false;
}
Thanks in advance for the help.
UPDATED: If I add this, it works. Is this because the two await calls are disconnected?
result.IsActive = employee.IsActive;
_envisonDbContext.Entry(result).State = EntityState.Modified;
Seems like you forgot update-method before savingchanges
if (result != null)
{
result.FirstName = employee.FirstName;
result.LastName = employee.LastName;
result.Phone = employee.Phone;
result.IsActive = employee.IsActive;
_envisionDbContext.Update(result); //paste it before you save changes
await _envisonDbContext.SaveChangesAsync();
return true;
}

ExecuteSqlRawAsync returns -1 in Entity Framework 3.1

In my ASP.NET Core 3.1 web application, I am mostly using stored procedures. When using ExecuteSqlRawAsync in Entity Framework Core it always returns -1. Below given is my generalized method to execute stored procedures.
public async Task<int> ExecuteSqlNonQuery(string StoredProcName, params object[] parameters)
{
int iTotalRecordsAffected = 0;
List<TEntity> listOfObject = null;
try
{
if (!string.IsNullOrEmpty(StoredProcName))
{
StringBuilder sbStoredProc = new StringBuilder();
sbStoredProc.Append("Exec ");
sbStoredProc.Append(StoredProcName);
if (parameters != null)
{
foreach (SqlParameter item in parameters)
{
if (listOfObject == null)
{
sbStoredProc.Append(" #");
listOfObject = new List<TEntity>();
}
else
{
sbStoredProc.Append(", #");
}
sbStoredProc.Append(item.ParameterName.Replace("#", ""));
if (item.Direction == System.Data.ParameterDirection.Output)
{
sbStoredProc.Append(" OUT");
}
}
}
iTotalRecordsAffected = await _DBContext.Database.ExecuteSqlRawAsync(sbStoredProc.ToString(), parameters);
}
}
catch (Exception ex)
{
}
finally
{
if (_DBContext.Database.GetDbConnection().State == System.Data.ConnectionState.Open)
{
_DBContext.Database.GetDbConnection().Close();
}
}
return iTotalRecordsAffected;
}
Here is my controller method that calls a SP to update data.
public async Task<int> UpdateCustomerData(EditCustomerDetail editCustomerDetail)
{
int iTotalRecordsEffected = 0;
try
{
List<SqlParameter> sqlParamList = new List<SqlParameter>()
{
new SqlParameter("#CustomerID",editCustomerDetail.CorporateID),
new SqlParameter("#CustomerName",editCustomerDetail.CorporateName),
new SqlParameter("#CustomerAddress",editCustomerDetail.Address),
new SqlParameter("#City",editCustomerDetail.City),
new SqlParameter("#CountryID",editCustomerDetail.CountryID),
new SqlParameter("#StateID",editCustomerDetail.StateID),
new SqlParameter("#Description",editCustomerDetail.Description),
new SqlParameter("#Phone",editCustomerDetail.Phone),
new SqlParameter("#Fax",editCustomerDetail.Fax),
new SqlParameter("#ModifiedBy",editCustomerDetail.UserID)
};
iTotalRecordsEffected = await _unitOfWork.GetRepository<EditCustomerDetail>().ExecuteSqlNonQuery("UpdateCustomerDetails", sqlParamList.ToArray());
}
catch (Exception ex)
{
}
finally
{
}
return iTotalRecordsEffected;
}
Any suggestion what I am doing wrong?

How to change below code from asp.net to razor page

I am new to Razor page but have been working in aspx. This below is my code - please help me convert this to a Razor page:
void Page_Load(object sender, EventArgs e)
{
foreach(string f in Request.Files.AllKeys)
{
HttpPostedFile file = Request.Files[f];
file.SaveAs("C:\\e_data\\WorkPage\\IMS18\\ALBAB_Dynamic\\20008\\Case_Manager\\" + file.FileName);
}
}
I want to change to razor page code.
Here's what I use for uploading a single file and storing the path to the file in a database. It'll explain the bits that Microsoft left out of it's docs (for instance the path to the base directory in .netcore2.2) Note that security is not much of a concern for me as this is a small company intranet... but there's bits in there about getting filename without extension, and you may want to store without the file extension for security reasons (or remove and then add your own extension):
public async Task<IActionResult> OnPostAsync()
{
if (id == null)
{
return NotFound();
}
Kit = await _context.Kits.FirstOrDefaultAsync(m => m.ID == id);
if (Kit == null)
{
return NotFound();
}
if (Request.Form.Files.Count > 0)
{
IFormFile file = Request.Form.Files[0];
string folderName = "UploadedOriginalBOMs";
string OrgBOMRootPath = Path.Combine(AppContext.BaseDirectory, folderName);
if (!Directory.Exists(OrgBOMRootPath))
{
Directory.CreateDirectory(OrgBOMRootPath);
}
string sFileExtension = Path.GetExtension(file.FileName).ToLower();
string fullPath = Path.Combine(OrgBOMRootPath, file.FileName);
// StringBuilder sb = new StringBuilder();
if (file.Length > 0)
{
String cleanFilename = Path.GetFileNameWithoutExtension(file.FileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
{
file.CopyTo(stream);
}
Kit.PathToOriginalBOM = "UploadedOriginalBOMs/" + file.FileName;
_context.Kits.Attach(Kit).State = EntityState.Modified;
await _context.SaveChangesAsync();
}
}
else
{
if (!ModelState.IsValid)
{
return Page();
}
}
return RedirectToPage("./Index");
}
You'll notice that you can just use the same forloop as in your .aspx file.

How can I do to Edit a record with losing the actual data of it?

The error I'am receiving when I try to upload a File on a record already existed, is this:
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
public ActionResult Edit(Project mcs, HttpPostedFileBase file, [Bind(Include
= "ProjectID,NumberMCP,EngineerID,SiteLocationID,nameProject,Ptype,Pyear,
Fr,
Fc, MCPcontent, Proj, ContentType")] Project project)
{
try
{
if (ModelState.IsValid)
{
if (file != null && file.ContentLength > 0)
{
System.IO.File.Delete(Path.Combine(Server.MapPath("~/UploadFiles/"), mcs.Proj));
string ds =
file.FileName.Substring(file.FileName.Length - 3);
string p = string.Empty;
p = Server.MapPath("~/UploadFiles/");
file.SaveAs(p + file.FileName);
BinaryReader br = new BinaryReader(file.InputStream);
byte[] buffer = br.ReadBytes(file.ContentLength);
using (db)
{
mcs.Proj = file.FileName;
mcs.ContentType = file.ContentType;
mcs.MCPcontent = buffer;
db.Projects.Add(mcs);
db.SaveChanges();
}
ViewBag.EngineerID = new SelectList(db.Engineers, "EngineerID", "eName", project.EngineerID);
ViewBag.SiteLocationID = new SelectList(db.SiteLocations, "SiteLocationID", "nameSL", project.SiteLocationID);
return RedirectToAction("Index");
}
else
{
TempData["Message"] = "No se elegió ningún
archivo.";
return RedirectToAction("Edit");
}
}
}
else
{
return View();
}
}
catch /*(Exception ex)*/
{
ViewBag.Message = "Upload failed";
return RedirectToAction("Edit");
}
}
I need some logic help in here please.

.Net Core Delete uploaded Files

I am using ASP.NET Core to upload files to my database.
Where I have two database, one for the create and for the files.
My code looks like this:
public async Task<IActionResult> Create([Bind("ID,Name,Email,Job Title,ICollection<IFormFile> uploads, Track track)
{
if (ModelState.IsValid)
{
_context.Add(track);
// Uploading files for the Request Database
foreach (var upload in uploads)
{
if (upload.Length > 0)
{
// Getting file into buffer.
byte[] buffer = null;
using (var stream = upload.OpenReadStream())
{
buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
}
// Converting buffer into base64 code.
string base64FileRepresentation = Convert.ToBase64String(buffer);
// Saving it into database.
_context.Upload.Add(new Request()
{
UploadName = string.Format("{0}_{1}", DateTime.UtcNow.ToString("yyyyMMddHHmmss"), Request.FileName),
Uploadcode = base64FileRepresentation,
TrackID = track.ID,
});
await _context.SaveChangesAsync();
}
}
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(track);
}
In the Edit page, I want to have a button to delete the file that was uploaded to the Track. I have tried to change the delete action from the Controller to the following code, but it didn't work:
[HttpPost, ActionName("DeleteRequest")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteRequest(int id)
{
var x= await _context.Upload.SingleOrDefaultAsync(m => m.UploadID == id);
_context.Upload.Remove(x);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
My view Code
<a asp-action="DeleteRequest"><span class="glyphicon glyphicon-trash" style="color:red;"></span></a>
when I click it, it takes me to empty page with this URL:
localhost:44444/Tracks/DeleteRequest
<a asp-action="DeleteRequest" asp-controller="UpdatYourControllerName"
asp-route-id="#model.UploadId"><span class="glyphicon glyphicon-trash" style="color:red;"></span></a>
public async Task<IActionResult> DeleteRequest(int id)
{
// here debug the id you passed is actually present in db
var x= await _context.Upload.FirstOrDefaultAsync(m => m.UploadID == id);
if(x!=null)
{
_context.Upload.Remove(x);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
}

Resources