Image File sets to null after updating only other fields - c#

am having a weird functionality when am only updating other fields other than the image , the other fields (FirstName , LastName) update successfully but then the Image sets its self to null, but when I choose it with respect to other fields (FirstName, LastName) it updates successfully. So what I want is when I don't update the image it stays as it is without setting its self to null.
This is my New.cshtm file which handles both Creating and Editing data :
<form asp-action="New" method="Post" asp-controller="Student" enctype="multipart/form-data">
<div asp-validation-summary="All"></div>
<input asp-for="Id" type="hidden"/>
<input name="IsEditMode" id="IsEditMode" value="#ViewBag.IsEditMode" type="hidden"/>
<div class="form-row">
<label>Upload Photo</label>
<input asp-for="ImageUrl" type="file" id="file" name="file" class="form-control"/>
</div>
<div class="form-row">
<div class="col">
<label asp-for="FirstName"></label>
<input asp-for="FirstName" class="form-control"/>
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="MiddleName"></label>
<input asp-for="MiddleName" class="form-control"/>
<span asp-validation-for="MiddleName" class="text-danger"></span>
</div>
</div>
</form>
Then these are the methods of my controller Student.cs am using to update the fields :
public IActionResult New(Student student, string IsEditMode, IFormFile file)
{
if (!ModelState.IsValid)
{
ViewBag.IsEditMode = IsEditMode;
return View(student);
}
try
{
if (IsEditMode.Equals("false"))
{
_studentRepository.Create(student);
UploadFile(file, student.Id);
_toastNotification.AddSuccessToastMessage("Student has been created successfully.");
}
else
{
_studentRepository.Edit(student);
UploadFile(file, student.Id);
_toastNotification.AddSuccessToastMessage("Student has been edited successfully.");
}
return RedirectToAction(nameof(Index));
}
catch (Exception e)
{
return RedirectToAction(nameof(Index));
}
}
public IActionResult Edit(int id)
{
try
{
ViewBag.IsEditMode = "true";
var student = _studentRepository.GetSingleStudent(id);
return View("New", student);
}
catch (Exception ex)
{
return Content("Could not find Pet");
}
}
public void UploadFile(IFormFile file, long studentId)
{
var fileName = file.FileName;
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images",fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
file.CopyTo(fileStream);
}
var student = _studentRepository.GetSingleStudent(studentId);
student.ImageUrl = fileName;
_studentRepository.Edit(student);
}
Then, this is how I am Updating in the Repository :
Then in my Repository, this is how I am updating the fields " :
public void Edit(Student student)
{
var existingStudent = _context.Students
.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student.
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
}
}
The Index.cshtml, this is one list the images and the First and LastName and the (action buttons) Edit, Delete buttons :
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<td ><b>Student Picture</b></td>
<td><b>FirstName</b></td>
<td><b>LastName</b></td>
<td colspan="2"> <b>Actions</b></td>
</tr>
</thead>
<tbody>
#foreach (var student in Model)
{
<tr>
<td>#student.StudentRegNo</td>
<td>
<div class="thumbnail">
<img src="/images/#student.ImageUrl" width="90" height="90"/>
</div>
</td>
<td>#student.FirstName</td>
<td>#student.LastName</td>
<d>
<td>
<a class="btn btn-warning" asp-action="Details" asp-controller="Student" asp-route-Id="#student.Id">Details</a>
</td>
<td>
<a class="btn btn-primary" asp-action="edit" asp-route-Id="#student.Id">Edit</a>
</td>
<td>
<a
class="btn btn-danger delete"
asp-route-Id="#student.Id"
asp-action="Delete">
Delete
</a>
</td>
</d>
</tr>
}
</tbody>
</table>
EDIT
This is the current logic am having according to #Raul solution, but it's not working :
if (student.ImageUrl != null)
{
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
}
else
{
_context.Entry(existingStudent).Property(x => x.ImageUrl).IsModified = false;
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
}

You could consider the two scenario separately.When updating fields without updating the image, the file is null, then you need to assgin the ImageUrl of existing student to the posted student.
//...
try
{
if (IsEditMode.Equals("false"))
{
_studentRepository.Create(student);
UploadFile(file, student.Id);
_toastNotification.AddSuccessToastMessage("Student has been created successfully.");
}
else
{
//edit mode
if(file == null)//Updating fields without updating the image.
{
var existingStudent = _context.Students.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student with previousImageUrl
student.ImageUrl = existingStudent.ImageUrl;
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.SaveChanges();
}
}
else//Updating the fields and the image
{
_studentRepository.Edit(student);
UploadFile(file, student.Id);
}
_toastNotification.AddSuccessToastMessage("Student has been edited successfully.");
}
return RedirectToAction(nameof(Index));
}
catch (Exception e)
{
return RedirectToAction(nameof(Index));
}
}
public void UploadFile(IFormFile file, long studentId)
{
var fileName = file.FileName;
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images", fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
file.CopyTo(fileStream);
}
var student = _studentRepository.GetSingleStudent(studentId);
student.ImageUrl = fileName;
_studentRepository.Edit(student);
}
public void Edit(Student student)
{
var existingStudent = _context.Students
.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student.
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.SaveChanges();
}
}

In your Edit student method, you can set the IsModified to false for your ImageUrl Property which will not update the image field in your database:
public void Edit(Student student)
{
var existingStudent = _context.Students.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
// updating student.
_context.Student.Attach(existingStudent);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.Entry(existingStudent).Property(x => x.ImageUrl).IsModified=false;
_context.SaveChanges();
}
}
Of course, you would need to check for your ImageUrl logic in this. If you get a new image then you update your model accordingly.
EDIT:
You can incorporate your if-else condidition like this:
if (student.ImageUrl != null)
{
_context.Student.Add(existingStudent);
_context.Entry(existingStudent).State EntityState.Modified;
//_context.Student.Update(existingStudent); //You can also use this. Comment out the upper two lines
_context.SaveChanges();
}
else
{
// updating student.
_context.Student.Attach(existingStudent);
_context.Entry(existingStudent).State = EntityState.Modified;
_context.Entry(existingStudent).Property(x => x.ImageUrl).IsModified=false;
_context.SaveChanges();
}

Related

How can I send data (or the entire model if possible) from view to the "Update" action in controller without using form?

My Index.cshtml view:
#addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers
#using Assignment3.Models
#model TblMatHang
<form id="frm" asp-controller="Home" asp-action="Index" method="post">
Product Code: <select name="maHang" onchange="onChange()">
#foreach (var item in ViewBag.MatHangs)
{
#if (ViewBag.SelectedID == item.MaHang)
{
<option value="#item.MaHang" selected>#item.MaHang</option>
}
else
{
<option value="#item.MaHang">#item.MaHang</option>
}
}
</select>
</form>
Product name
<form asp-controller="Home" asp-action="FilterName" method="post">
<input type="text" name="Fname" asp-for="Tenhang" />
<button type="submit">Filter by Name</button>
</form>
Unit
<input type="text" asp-for="Dvt" />
<br />
<form asp-controller="Home" asp-action="FilterPrice" method="post">
Old Price
<input type="number" name="oldP" asp-for="Gia" /> --> New
<input type="number" name="newP" />
<button type="submit">Filter by Price</button>
</form>
Image link
<form asp-controller="Home" asp-action="FilterImage" method="post">
<input type="text" asp-for="Image" name="Image" />
<button type="submit">Filter by Image</button>
</form>
<table>
<tr>
<td>
<form asp-controller="Home" asp-action="Update" method="post">
<button type="submit">UPDATE</button>
</form>
</td>
<td>
<form asp-controller="Home" asp-action="Index">
<button type="submit">RESET</button>
</form>
</td>
</tr>
</table>
<script>
function onChange() {
document.getElementById("frm").submit();
}
</script>
<br />
Danh sach mat hang:
<form id="frm" asp-controller="Home" asp-action="Index" method="post">
<table border="1">
<tr>
<th>Ma Hang</td>
<th>Ten Hang</th>
<th>DVT</th>
<th>Gia</th>
<th>Image</th>
</tr>
#foreach (var item in ViewBag.MatHangs)
{
<tr>
<td>#item.MaHang</td>
<td>#item.Tenhang</td>
<td>#item.Dvt</td>
<td>#item.Gia</td>
<td>#item.Image</td>
</tr>
}
</table>
</form>
HomeController:
using Assignment3.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
namespace Assignment3.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
using (MyOrderContext context = new MyOrderContext())
{
var list = context.TblMatHangs.ToList();
ViewBag.MatHangs = context.TblMatHangs.ToList();
return View();
}
}
[HttpPost]
public IActionResult Index(string maHang)
{
using (MyOrderContext context = new MyOrderContext())
{
ViewBag.SelectedID = maHang;
ViewBag.MatHangs = context.TblMatHangs.ToList();
TblMatHang m = context.TblMatHangs
.SingleOrDefault(x => x.MaHang == maHang);
return View(m);
}
}
[HttpPost]
public IActionResult FilterName(string fname)
{
string search = fname;
using (MyOrderContext context = new MyOrderContext())
{
ViewBag.MatHangs = context.TblMatHangs.ToList();
TblMatHang m = context.TblMatHangs
.FirstOrDefault(x => x.Tenhang.ToLower().Contains(search));
ViewBag.MatHangs = context.TblMatHangs
.Where(x => x.Tenhang.ToLower().Contains(search)).ToList();
return View("Index", m);
}
}
public IActionResult FilterPrice(float oldP, float newP)
{
float oldPrice = oldP;
float newPrice = newP;
using (MyOrderContext context = new MyOrderContext())
{
ViewBag.MatHangs = context.TblMatHangs.ToList();
TblMatHang m = context.TblMatHangs
.FirstOrDefault(x => x.Gia > oldPrice && x.Gia < newPrice);
ViewBag.MatHangs = context.TblMatHangs
.Where(x => x.Gia > oldPrice && x.Gia < newPrice).OrderBy(x => x.Gia).ToList();
return View("Index", m);
}
}
[HttpPost]
public IActionResult Update(TblMatHang m)
{
using (MyOrderContext context = new MyOrderContext())
{
m = new TblMatHang
{
};
return View(m);
}
}
[HttpPost]
public IActionResult FilterImage(string image)
{
string search = image;
using (MyOrderContext context = new MyOrderContext())
{
ViewBag.MatHangs = context.TblMatHangs.ToList();
TblMatHang m = context.TblMatHangs
.FirstOrDefault(x => x.Image.ToLower().Contains(search));
ViewBag.MatHangs = context.TblMatHangs
.Where(x => x.Image.ToLower().Contains(search)).ToList();
return View("Index", m);
}
}
}
}
I'm intend to update the information of the corresponding product by passing model from Index view to the Update controller, changing its attributes' values, saving changes then returning to view to be shown on the table below.
I've also tried using nested form and javascript but it just didn't work/or generated a lot of unwanted problems.
Sorry for those non-English names.

How to persist filterdata when sorting ASP.NET CORE MVC

I'm trying to make a table that has searching, sorting, and filtering (any number of available filters). When I sort the filters get overwritten and I'm not sure how to make sure they stay in the querystring since they are stored in the model as an array of strings.
I've tried using the ViewBag and the asp-route-varName tag but it didn't work since it's an array. I thought since they are all in the same form that they should just append to the querystring not overwrite it. The sort and search works since search is just a string. The filter and search works not entirely sure why.
View:
#model ScenarioLake.Api.Host.WebApplication.Models.MasterModel;
<form asp-controller="FileList" asp-action="Index" method="get">
<p>
Title: <input type="text" name="SearchString" />
<input type="submit" value="Filter" />
<a asp-action="Index">Full List</a>
</p>
<select class="chosen-select" multiple="multiple" name="filters" asp-for="filters"
asp-items="Model.filterModel.filters[0].values;"></select>
<input type="submit" />
<table class="table">
<thead>
<tr>
<th>
<a asp-controller="FileList" asp-action="Index" asp-route-searchString="#Model.searchString" asp-route-sortOrder="#ViewData["NameSortParm"]">
#Html.DisplayNameFor(model => model.files.FirstOrDefault().Name)
</a>
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.files)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.Guid">Edit</a> |
<a asp-action="Details" asp-route-id="#item.Guid">Details</a> |
<a asp-action="Delete" asp-route-id="#item.Guid">Delete</a>
</td>
</tr>
}
</tbody>
</table>
</form>
Model:
public class MasterModel
{
public FilterFileModel filterModel { get; set;}
public List<FileDisplay> files;
public string[] filters { get; set; }
public string searchString { get; set; }
}
Controller Index Method:
public async Task<IActionResult> Index(string sortOrder, string searchString, MasterModel model)
{
ViewData["NameSortParm"] = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
IGetFileListHandler fileListHandler = _restServiceFactory.CreateGetFileListHandler();
GetFileListRequest fileListRequest = new GetFileListRequest();
IGetFileListResponse response = await fileListHandler.ProcessRequest(fileListRequest);
var items = new List<FileDisplay>();
IGetFileAttributesHandler fileAttributesHandler = _restServiceFactory.CreateGetFileAttributesHandler();
GetFileAttributesRequest fileAttributesRequest = new GetFileAttributesRequest();
IGetFileAttributesResponse fileAttributesResponse = await fileAttributesHandler.ProcessRequest(fileAttributesRequest);
IGetFileFileAttributeHandler fileFileAttributesHandler = _restServiceFactory.CreateGetFileFileAttributeHandler();
GetFileFileAttributeRequest fileFileAttributesRequest = new GetFileFileAttributeRequest();
IGetFileFileAttributeResponse fileFileAttributesResponse = await fileFileAttributesHandler.ProcessRequest(fileFileAttributesRequest);
var fileFileAttribute = fileFileAttributesResponse.FileFileAttributes;
IEnumerable<Entities.Public.Interfaces.IFile> responseFilteredFiles = response.Files;
FilterFileModel fileFilter = new FilterFileModel();
fileFilter.filters = new List<FileFilter>();
if (!ReferenceEquals(fileAttributesResponse, null) && !ReferenceEquals(fileAttributesResponse.Values, null))
{
fileFilter.types = fileAttributesResponse.Values.Select(s => s.Type).Distinct().ToList(); // query fileattribute repo to get all types of filters
foreach (var type in fileFilter.types)
{
FileFilter filter = new FileFilter();
filter.type = type;
filter.values = fileAttributesResponse.Values.Where(s => s.Type == type).Select(s => new SelectListItem()
{
Value = s.Value,
Text = s.Value
}).Distinct().ToList();
fileFilter.filters.Add(filter);
}
}
if (!ReferenceEquals(response, null) && !ReferenceEquals(response.Files, null))
{
if (!String.IsNullOrEmpty(searchString))
{
responseFilteredFiles = responseFilteredFiles.Where(s => s.FileName.Contains(searchString));
model.searchString = searchString;
}
switch(sortOrder)
{
case "name_desc":
responseFilteredFiles = responseFilteredFiles.OrderByDescending(s => s.FileName);
break;
default:
responseFilteredFiles = responseFilteredFiles.OrderBy(s => s.FileName);
break;
}
}
if (model.filters != null)
{
if (model.filters.Length != 0)
{
IEnumerable<int> attributeIds = fileAttributesResponse.Values.Where(s => model.filters.Contains(s.Value)).Select(s => s.FileAttributeId);
IEnumerable<int> fileIds = fileFileAttribute.Where(s => attributeIds.Contains(s.FileAttributeId)).Select(s => s.FileId);
responseFilteredFiles = responseFilteredFiles.Where(s => fileIds.Contains(s.FileId));
}
}
foreach (var item in responseFilteredFiles)
{
var file = new FileDisplay()
{
Name = item.FileName,
Guid = item.Guid,
FileId = item.FileId
};
items.Add(file);
}
model.filterModel = fileFilter;
model.files = items;
return View(model);
}
The expected result is that the filter and search data persists when a user changes the sort. The actual results are only the search persists, I don't care about the sort persisting when the filters or search are changed.

file control doesn't initialized in edit page - razor pages

I use asp.net core razor pages to create my application, in my create page, I have two file controls, one for upload icon image and the other for uploading detail images. But when I click edit button, all of the fields were initialized, except the two file controls. Please check my code. Anyone can help?
In my razor page:
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="Product.Icon" class="control-label"></label>
<input asp-for="#Model.Icon" type="file" />
<span asp-validation-for="Product.Icon" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label”>Detail Images(support multi-uploading):</label>
<input type="file" id="fUpload" name="files" multiple />
</div>
</div>
</div>
In my page model:
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
Product = await _context.Products
.Include(p => p.Shop).SingleOrDefaultAsync(m => m.ID == id);
if (Product == null)
{
return NotFound();
}
ViewData["Shop"] = new SelectList(_context.Shops, "ID", "Name");
return Page();
}
public async Task<IActionResult> OnPostAsync(List<IFormFile> files)
{
if (!ModelState.IsValid)
{
return Page();
}
var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
if (!Directory.Exists(uploads))
{
Directory.CreateDirectory(uploads);
}
if (this.Icon != null)
{
var fileName = GetUniqueName(this.Icon.FileName);
var filePath = Path.Combine(uploads, fileName);
this.Icon.CopyTo(new FileStream(filePath, FileMode.Create));
this.Product.Icon = fileName;
}
if (files != null && files.Count > 0)
{
foreach (IFormFile item in files)
{
if (item.Length > 0)
{
var fn = GetUniqueName(item.FileName);
var fp = Path.Combine(uploads, fn);
item.CopyTo(new FileStream(fp, FileMode.Create));
this.Product.ProductImages = this.Product.ProductImages + fn + "^";
}
}
}
_context.Attach(Product).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(Product.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
The most important part of your page is missing from the code you provided - the <form> tag. For file uploading to work, you must specify that the method is post and you must also provide an enctype attribute with its value set to multipart/form-data:
<form method="post" enctype="multipart/form-data">
...
Ref: https://www.learnrazorpages.com/razor-pages/forms/file-upload

How to POST a form via Ajax to c# asp.net core controller method

As a newbie in ASP.NET Core, this is my first time trying to make an ajax call to asp.net controller method with jquery and I am finding it difficult. Below is my view form, my javascript file and my controller method;
The view form
<form id="components-form">
#Html.AntiForgeryToken();
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="entryformLabel">Payment Entries</h4>
</div>
<div class="modal-body">
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped" id="list-table">
<thead>
<tr>
<th>Entry</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
#foreach (var ent in ViewBag.staffEntries)
{
<tr>
<th>#ent.EntryLabel</th>
<th><input type="text" class="form-control entry" name="component[#ent.EntryId]" id="#ent.EntryId" value="#ent.EntryValue" /></th>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" id="update-entries-btn" class="btn btn-success"><span class="fa fa-check"></span> Update Entries</button>
</div>
</form>
The Javascript file
$(document).ready(function ()
{
var updateBtn = $("#update-entries-btn").click(function ()
{
$("#update-entries-btn").click(function () {
var token = $("[name=__RequestVerificationToken").val();
var postedValues = new FormData();
postedValues.append("__RequestVerificationToken", token);
$(".entry").each(function () {
var id = this.id;
var val = this.val;
postedValues.append(id,val);
});
var postUrl = "/staff/updatecomponents";
$.post(postUrl, postedValues, function (result) {
alert(result);
});
})
})
}
);
The controller method. I'm actually lost on how to handle the request at this point. Doint this returns null.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult updatecomponents(string posted)
{
return Json(posted);
}
I will appreciate a guide to get this working.
Thank you
After some more research, I solved this thus:
The Javascript code
$(document).ready(function ()
{
$("#update-components-btn").click(function ()
{
var token = $("[name=__RequestVerificationToken").val();
var staffId = $("[name=staffId").val();
var postedValues = {};
postedValues["__RequestVerificationToken"] = token;
postedValues.StaffId = staffId;
postedValues.StaffComponents = [];
$(".entry").each(function ()
{
var component = {};
component.StaffId = staffId;
component.EntryId = $(this).attr('id');
component.ValueAmount = Number($(this).val());
postedValues.StaffComponents.push(component);
});
var postUrl = "/staff/updatecomponents";
$.post(postUrl, postedValues, function (result)
{
var report = JSON.parse(JSON.stringify(result));
if (report.status)
{
swal("<span class=fa fa-thumbs-up", report.message, "success");
setInterval(function () { window.location.reload(true); }, 5000);
}
else
{
swal("<span class=fa fa-thumbs-down", report.message, "error");
}
});
});
}
);
I had to create a model that would emulate the expected object
public class StaffEntryUpdateModel
{
public string RequestToken { get; set; }
public string StaffId { get; set; }
public List<StaffEntry> StaffComponents { get; set; }
}
And finally the server side endpoint that receives and processes the ajax post
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult updatecomponents(StaffEntryUpdateModel postedData)
{
try
{
if (postedData.StaffComponents.Any())
{
ApplicationUser Staff = db.Users.FirstOrDefault(s => s.Id == postedData.StaffId);
if (Staff == null)
{
return new JsonResult(new { Status = false, Message = "Unknown staff" });
}
db.StaffEntries.Where(se => se.StaffId == postedData.StaffId).Delete();
foreach (var c in postedData.StaffComponents)
{
db.StaffEntries.Add(c);
}
int inserted = db.SaveChanges();
return new JsonResult(new { Status = (inserted > 0) ? true : false, Message = inserted + " components updated for staff" });
}
else
{
return new JsonResult(new { Status = false, Message = "No component sent for update for staff" });
}
}
catch (Exception e)
{
return new JsonResult(new {Status=false,Message=e.Message.ToString() });
}
}
In the process of working and reviewing the code, I had to change some items from the way it appeared in the original question but its basically the same.
I hope this helps someone looking for such solution anytime.
Thank you #Chetan Ranpariya for your attempt to help

Return to same page

I try to upload a file. But if the user doesnt select a file, the same page has to been seen with a message that you have to upload a file.
I have this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadFile([Bind(Include = "UploadData,Directories")] /*LibraryUploadModel libraryUpload*/ UploadViewModel uploadViewModel, string designId, string folder, FormLibraryEntry formLibraryEntry, string command)
{
//ActionResultSpecification result = SfsHelpers.GeneralHelper.HandleLibraryOverwrite(formLibraryEntry.Guid, this, command, FormRootPath, customerSchema, LibraryMode.FormLibrary);
try
{
if ((uploadViewModel.UploadData != null) && (uploadViewModel.UploadData.ContentLength > 0) && !string.IsNullOrEmpty(uploadViewModel.UploadData.FileName))
{
var fileName = Path.GetFileName(uploadViewModel.UploadData.FileName);
TemplateLibraryEntry entry = GetTemplateLibraryEntry(designId, customerSchema);
var path = Path.Combine(Server.MapPath("~/"), entry.FilePath, folder.Replace('/', '\\').Trim('\\'), fileName);
uploadViewModel.UploadData.SaveAs(path);
}
else
return Json(new { Message = "Error in saving file, Go back and try again" });
// return RedirectToAction("UploadFile");
//return View(uploadViewModel);
}
catch (Exception)
{
throw;
}
return RedirectToAction("Index");
}
}
But now the json message is shown. The name of the page where you can upload is UploadFile.
I have it now like this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadFile([Bind(Include = "UploadData,Directories")] /*LibraryUploadModel libraryUpload*/ UploadViewModel uploadViewModel, string designId, string folder, FormLibraryEntry formLibraryEntry, string command)
{
//ActionResultSpecification result = SfsHelpers.GeneralHelper.HandleLibraryOverwrite(formLibraryEntry.Guid, this, command, FormRootPath, customerSchema, LibraryMode.FormLibrary);
try
{
if ((uploadViewModel.UploadData != null) && (uploadViewModel.UploadData.ContentLength > 0) && !string.IsNullOrEmpty(uploadViewModel.UploadData.FileName))
{
var fileName = Path.GetFileName(uploadViewModel.UploadData.FileName);
TemplateLibraryEntry entry = GetTemplateLibraryEntry(designId, customerSchema);
var path = Path.Combine(Server.MapPath("~/"), entry.FilePath, folder.Replace('/', '\\').Trim('\\'), fileName);
uploadViewModel.UploadData.SaveAs(path);
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("uploadViewModel", "your message");
return View(uploadViewModel);
}
catch (Exception)
{
throw;
}
}
and the view like this:
<div class="col-md-offset-2 col-md-10">
<table>
#for (var i = 0; i < Model.Directories.Count; i++)
{
<tr>
<td>
<fieldset>
<input type="radio" name="folder" value="#Model.Directories[i]" id="folder(#i)">
<label for="folder(#i)">#Model.Directories[i]</label>
</fieldset>
</td>
</tr>
}
</table>
</div>
but the problem is that if you press on Uploaden without an upload file, I get this error:
Line 55: <div class="col-md-offset-2 col-md-10">
Line 56: <table>
Line 57: #for (var i = 0; i < Model.Directories.Count; i++)
Line 58: {
Line 59: <tr>
Source File: b:\Seneca\Producten\FormsServer\Trunk\SenecaFormsServer\Areas\Dashboard\Views\DesignTemplate\UploadFile.cshtml Line: 57
and the directories are null: Model.Directories = null
The problem you have is that you are binding your Directories to your view, but the name attribute of your radio button isn't correctly formed so it won't be posted to the server. Subsequently, when you send the view back with the model that property will be null. Whilst you're at it, use LabelFor as well.
Change it to the following:
#for (var i = 0; i < Model.Directories.Count; i++)
{
<tr>
<td>
<fieldset>
#Html.RadioButtonFor(m => m.Directories, Model.Directories[i])
#Html.LabelFor(m => m.Directories[i])
</fieldset>
</td>
</tr>
}

Categories