MVC Parent Child Modal File Upload problem - c#

I have a parent child scenario for getting header detail data. here is my code attached, the problem is when i use a file upload it does not work
Person Model:
public class Person
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
[Display(Name = "First Name")]
[Required]
[StringLength(255, MinimumLength = 3)]
public string Name { get; set; }
[Display(Name = "Last Name")]
[Required]
[StringLength(255, MinimumLength = 3)]
public string Surname { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Error: Must Choose a Country")]
[Range(1, int.MaxValue, ErrorMessage = "Select a Country")]
public int CountryID { get; set; }
public virtual Country Country { get; set; }
}
Address Model:
public class Address
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Error: Must Choose a City")]
[Range(1, int.MaxValue, ErrorMessage = "Select a City")]
public int CityID { get; set; }
public virtual City City { get; set; }
[Required]
[Display(Name = "Street Address")]
public string Street { get; set; }
[Required]
[DataType(DataType.ImageUrl)]
public string ImageUrl { get; set; }
[NotMapped]
[DataType(DataType.Upload)]
public HttpPostedFileBase ImageUpload { get; set; }
[Required]
[Phone]
public string Phone { get; set; }
public int PersonID { get; set; }
public virtual Person Person { get; set; }
}
PeopleController:
private DataDb db = new DataDb();
// GET: People
public async Task<ActionResult> Index()
{
return View(await db.People.ToListAsync());
}
// GET: People/Details/5
public async Task<ActionResult> Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Person person = await db.People.Where(p => p.Id == id).Include(p => p.Addresses).SingleAsync();
if (person == null)
{
return HttpNotFound();
}
return View(person);
}
// GET: People/Edit/5
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var person = await db.People
.Include(p => p.Addresses)
.Where(p => p.Id == id)
.SingleAsync();
if (person == null)
{
return HttpNotFound();
}
ViewBag.CountryID = new SelectList(db.Country, "CountryID", "CountryName", person.CountryID);
return View(person);
}
// POST: People/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit( Person person)
{
if (ModelState.IsValid)
{
db.Entry(person).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.CountryID = new SelectList(db.Country, "CountryID", "CountryName", person.CountryID);
return View(person);
}
// GET: People/Delete/5
public async Task<ActionResult> Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Person person = await db.People.FindAsync(id);
if (person == null)
{
return HttpNotFound();
}
return View(person);
}
// POST: People/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(int id)
{
Person person = await db.People.FindAsync(id);
db.People.Remove(person);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
Address Controller:
private DataDb db = new DataDb();
public ActionResult Index(int id)
{
ViewBag.PersonID = id;
var addresses = db.Addresses.Where(a => a.PersonID == id).OrderBy(a => a.City.CityName);
return PartialView("_Index", addresses.ToList());
}
[ChildActionOnly]
public ActionResult List(int id)
{
ViewBag.PersonID = id;
var addresses = db.Addresses.Where(a => a.PersonID == id);
return PartialView("_List", addresses.ToList());
}
public ActionResult Create(int PersonID)
{
//Address address = new Address();
//address.PersonID = PersonID;
//FillCity(address);
Address adv = new Address();
adv.PersonID = PersonID;
FillCityModel(adv);
return PartialView("_Create", adv);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Address address, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
int addressID = clsStatic.newAddressID();
address.Id = addressID;
var uploadDir = "~/images";
var imagePath = Path.Combine(Server.MapPath(uploadDir), address.ImageUpload.FileName);
var imageUrl = Path.Combine(uploadDir, address.ImageUpload.FileName);
address.ImageUpload.SaveAs(imagePath);
address.ImageUrl = imageUrl;
db.Addresses.Add(address);
db.SaveChanges();
string url = Url.Action("Index", "Addresses", new { id = address.PersonID });
return Json(new { success = true, url = url });
}
FillCity(address);
return PartialView("_Create", address);
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Address address = db.Addresses.Find(id);
if (address == null)
{
return HttpNotFound();
}
//ViewBag.CityID = new SelectList(db.City, "CityID", "CityName", address.CityID);
FillCity(address);
return PartialView("_Edit", address);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Address address )
{
var uploadDir = "~/images";
if (address.ImageUpload != null)
{
var imagePath = Path.Combine(Server.MapPath(uploadDir), address.ImageUpload.FileName);
var imageUrl = Path.Combine(uploadDir, address.ImageUpload.FileName);
address.ImageUpload.SaveAs(imagePath);
address.ImageUrl = imageUrl;
}
if (ModelState.IsValid)
{
db.Entry(address).State = EntityState.Modified;
db.SaveChanges();
string url = Url.Action("Index", "Addresses", new { id = address.PersonID });
return Json(new { success = true, url = url });
}
//var file = Request.Files[0];
//if (file != null && file.ContentLength > 0)
//{
// var fileName = address.Id + Path.GetExtension(file.FileName);
// var path = Path.Combine(Server.MapPath("~/Images/Addresses/"), fileName);
// file.SaveAs(path);
//}
FillCity(address);
//ViewBag.CityID = new SelectList(db.City, "CityID", "CityName", address.CityID);
return PartialView("_Edit", address);
}
private void FillCity(Address address)
{
List<SelectListItem> city = new List<SelectListItem>();
foreach (City item in db.City)
{
if (item.CityID != address.CityID)
city.Add(new SelectListItem { Text = item.CityName, Value = item.CityID.ToString() });
else
city.Add(new SelectListItem { Text = item.CityName, Value = item.CityID.ToString(), Selected = true });
}
ViewBag.CityID = city;
}
private void FillCityModel(Address address)
{
List<SelectListItem> city = new List<SelectListItem>();
foreach (City item in db.City)
{
if (item.CityID != address.CityID)
city.Add(new SelectListItem { Text = item.CityName, Value = item.CityID.ToString() });
else
city.Add(new SelectListItem { Text = item.CityName, Value = item.CityID.ToString(), Selected = true });
}
ViewBag.CityID = city;
}
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Address address = db.Addresses.Find(id);
if (address == null)
{
return HttpNotFound();
}
return PartialView("_Delete", address);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Address address = db.Addresses.Find(id);
db.Addresses.Remove(address);
db.SaveChanges();
string url = Url.Action("Index", "Addresses", new { id = address.PersonID });
return Json(new { success = true, url = url });
}
Here in _Edit View of Address I want to have File Upload Field
#model TestAjax.Models.Address
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Edit Address</h4>
</div>
<div class="modal-body">
#using (Html.BeginForm("Edit", "Addresses", FormMethod.Post,
new { id = "editForm", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.PersonID)
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.CityID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.CityID, (List<System.Web.Mvc.SelectListItem>)ViewBag.CityID, new { #class = "form-control selectpicker" })
#Html.ValidationMessageFor(model => model.CityID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Street, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Street, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Street, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Phone, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Phone, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Phone, "", new { #class = "text-danger" })
</div>
</div>
<div class="editor-field">
#Html.LabelFor(m => m.ImageUpload)
#Html.TextBoxFor(m => m.ImageUpload, new { type = "file" })
</div>
</div>
<button class="btn" type="button" data-dismiss="modal">Cancel</button>
<input class="btn btn-primary" type="submit" value="Save" />
}
</div>
<div class="modal-footer">
Footer
</div>
<script>
$(document).ready(function () {
refill();
});
function refill() {
var id = #Model.CityID;
$('#CityID').val(id);
}
</script>
But when i press the save button in address controller edit action i don't have the file selected.
please help.
Download Source Code

Related

HttpPostedFileBase is null every time I make changes asp.net mvc

This is my Album model class.
public class Album
{
[Required(ErrorMessage ="Please enter an album title.")]
public string Title { get; set; }
[Key]
public int Id { get; set; }
[Required(ErrorMessage ="Please enter an album price.")]
[Range(0.01,double.MaxValue,ErrorMessage ="Price cannot be 0 or lower.")]
public decimal Price { get; set; }
[Required]
public int ArtistId { get; set; }
[Required]
public virtual Artist Artist { get; set; }
[Required]
public int GenreId { get; set; }
[Required]
public virtual Genre Genre { get; set; }
public byte[] ImageData { get; set; }
public string ImageMimeType { get; set; }
}
The repository and the implementation of the SaveAlbum method
public interface IAlbumRepository
{
IEnumerable<Album> Albums { get; }
void SaveAlbum(Album album);
Album DeleteAlbum(int albumId);
}
public void SaveAlbum(Album album)
{
if (album.Id == 0)
{
if (context.Albums.Where(a => a.Artist.Name == album.Artist.Name).FirstOrDefault() != null)
{
album.ArtistId = context.Albums.Where(a => a.Artist.Name == album.Artist.Name).FirstOrDefault().ArtistId;
album.Artist = context.Albums.Where(a => a.Artist.Name == album.Artist.Name).FirstOrDefault().Artist;
}
if (context.Albums.Where(a => a.Genre.Name == album.Genre.Name).FirstOrDefault() != null)
{
album.GenreId = context.Albums.Where(a => a.Genre.Name == album.Genre.Name).FirstOrDefault().GenreId;
album.Genre = context.Albums.Where(a => a.Genre.Name == album.Genre.Name).FirstOrDefault().Genre;
}
context.Albums.Add(album);
}
else
{
Album dbEntry = context.Albums.Find(album.Id);
if (dbEntry!= null)
{
if (context.Albums.Where(a => a.Artist.Name == album.Artist.Name).FirstOrDefault() != null)
{
dbEntry.ArtistId = context.Albums.Where(a => a.Artist.Name == album.Artist.Name).FirstOrDefault().ArtistId;
dbEntry.Artist = context.Albums.Where(a => a.Artist.Name == album.Artist.Name).FirstOrDefault().Artist;
}
else
{
dbEntry.ArtistId = album.ArtistId;
dbEntry.Artist = album.Artist;
}
if (context.Albums.Where(a => a.Genre.Name == album.Genre.Name).FirstOrDefault() != null)
{
dbEntry.GenreId = context.Albums.Where(a => a.Genre.Name == album.Genre.Name).FirstOrDefault().GenreId;
dbEntry.Genre = context.Albums.Where(a => a.Genre.Name == album.Genre.Name).FirstOrDefault().Genre;
}
else
{
dbEntry.GenreId = album.GenreId;
dbEntry.Genre = album.Genre;
}
dbEntry.Id = album.Id;
dbEntry.ImageData = album.ImageData;
dbEntry.ImageMimeType = album.ImageMimeType;
dbEntry.OrderDetails = album.OrderDetails;
dbEntry.Price = album.Price;
dbEntry.Title = album.Title;
}
}
context.SaveChanges();
}
The controller
...
private IAlbumRepository repository;
public AdminController(IAlbumRepository repo)
{
repository = repo;
}
public ViewResult Index()
{
return View(repository.Albums);
}
public ViewResult Edit(int albumId)
{
Album album = repository.Albums.FirstOrDefault(m => m.Id == albumId);
return View(album);
}
[HttpPost]
public ActionResult Edit(Album album, HttpPostedFileBase image = null)
{
if (ModelState.IsValid)
{
if (image != null)
{
album.ImageMimeType = image.ContentType;
album.ImageData = new byte[image.ContentLength];
image.InputStream.Read(album.ImageData, 0, image.ContentLength);
}
repository.SaveAlbum(album);
TempData["message"] = string.Format("{0} has been saved", album.Title);
return RedirectToAction("Index");
}
else
{
return View(album);
}
}}
The Edit View
#model MusicStore1.Models.Album
#{
ViewBag.Title = "Admit: Edit " + #Model.Title;
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<div>
<div> <br /></div>
<div>
<h3> Edit #Model.Title </h3>
</div>
#using (Html.BeginForm("Edit", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary()
<div>
#Html.HiddenFor(m => m.Id)
<label> Title </label>
#Html.TextBoxFor(m => m.Title, null, new { #class = "form-control" })
<label> Artist </label>
#Html.TextBoxFor(m => m.Artist.Name, null, new { #class = "form-control" })
<label> Genre </label>
#Html.TextBoxFor(m => m.Genre.Name, null, new { #class = "form-control" })
<label> Price </label>
#Html.TextBoxFor(m => m.Price, null, new { #class = "form-control" })
<div class="form-group">
<div style="position:relative;">
<label> Image </label>
<a class="btn" href="javascript:;">
<input type="file" name="Image" size="40"
style="position:absolute" ;z-index:2;top:0;left:0;filter:alpha(opacity=0);opacity:0;
background-color:transparent; color:transparent;"
onchange='$("#upload-file-info").html($(this).val());' />
</a>
<span class="label label-info" id="upload-file-info"></span>
</div>
#if (Model.ImageData == null)
{
<div class="form-control-static"> No Image</div>
}
else
{
<img class="img-thumbnail" width="150" height="150" src="#Url.Action("GetImage","Album", new { Model.Id })" />
}
</div>
</div>
<div>
<input type="submit" value="save" class="btn btn-success" />
#Html.ActionLink("Cancel and return to List", "Index", null, new
{
#class = "btn btn-info"
})
</div>
}
</div>
The GetImage method
public FileContentResult GetImage(int albumId)
{
Album alb = repository.Albums.FirstOrDefault(p => p.Id == albumId);
if (alb != null)
{
return File(alb.ImageData, alb.ImageMimeType);
}
else
{
return null;
}
}
Every time I try to change something about the album, like its title or price the image I've already saved gets lost after I save the changes. If anyone can help me and figure out what the problem is I'd be really grateful. Thanks in advance!
I think error in this line. You did not pass the albumId parameter correctly from view.
<img class="img-thumbnail" width="150" height="150"
src="#Url.Action("GetImage","Album", new { Model.Id })" />
Resolution:
Use this to pass albumId from view to controller
<img class="img-thumbnail" width="150" height="150"
src="#Url.Action("GetImage","Album", new { albumId = Model.Id })" />

Show All Countries in Drop down menu

I am registering Cities and for that I want a drop down menu of Countries. The data comes correctly on controller but after that it show errors.
Here is my code 'Model View'
public class CountryCityViewModel
{
public int CountryId { get; set; }
public string name { get; set; }
public SelectList CountryList { get; set; }
public string CountryListId{ get; set; }
}
'CityController'
public async Task<IActionResult> Create()
{
var result = await _countryService.GetAllCountriesCity();
ViewBag.Cities = result;
return View(result);
}
'HTML'
<div class="form-group col-sm-6">
#Html.LabelFor(model => model.CountryId, "Country", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownList(, new SelectList(ViewBag.Cities, "CountryId", "Name"))
#Html.ValidationMessageFor(model => model.CountryId, "", new { #class = "text-danger" })
</div>
'City Service Class'
public async Task<IEnumerable<CountryCityViewModel>> GetAllCountriesCity()
{
var uri = $"{_siteConfiguration.ApiBaseUrl}{ApiEndPoint.Get_Countries_All}";
var response = _httpClient.GetAsync(uri).Result;
var contents = response.Content.ReadAsStringAsync().Result;
var result = JsonConvert.DeserializeObject<IEnumerable<CountryCityViewModel>>(contents);
return await Task.FromResult(result);
}
YourPage.cshtml
#{
var list = _countryService.GetAllCountriesCity().Select(x => new SelectListItem()
{
Value = x.CountryId.ToString(),
Text = x.Name
}).ToList();
}
<select asp-items="#list" asp-for="CountryId" class="form-control"></select>

ASP.NET Core 2.0 Retrieve/Remove DropDownList Values

I'm creating an application were employees enter their First/Last Name, select their Department and Appointment from drop down lists. The CRUD Operations all work fine.
However, I need to remove the value(s) from the Appointments drop down list that have already been assigned to an employee. There can only be one employee per Appointment. So, I need to remove the Appointments from the Appointments drop down list after a user selects one.
I'm using ASP.NET Core 2.0, C#, EntityFrameworkCore Code First and SQL Server 2016.
I'm attaching my code that I have now if someone could possible assist. Thank you in advance!
Models
public class Employee
{
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int DepartmentID { get; set; }
public Department Department { get; set; }
public int AppointmentID { get; set; }
public Appointment Appointment { get; set; }
}
public class Department
{
public int DepartmentID { get; set; }
public string Name { get; set; }
public ICollection<Employee> Employees { get; set; }
}
public class Appointment
{
public int AppointmentID { get; set; }
public string TimeSlot { get; set; }
public ICollection<Employee> Employees { get; set; }
}
ViewModels
public class EmployeeFormVM
{
public int EmployeeID { get; set; }
[Required(ErrorMessage = "Please enter your First Name")]
[Display(Name = "First Name")]
[StringLength(50)]
public string FirstName { get; set; }
[Required(ErrorMessage = "Please enter your Last Name")]
[Display(Name = "Last Name")]
[StringLength(50)]
public string LastName { get; set; }
[Required(ErrorMessage = "Please select your Department")]
[Display(Name = "Department")]
public int DepartmentID { get; set; }
public IEnumerable<Department> Departments { get; set; }
[Required(ErrorMessage = "Please select your Appointment")]
[Display(Name = "Appointment")]
public int AppointmentID { get; set; }
public IEnumerable<Appointment> Appointments { get; set; }
}
DbContext
public class WinTenDbContext : DbContext
{
public WinTenDbContext(DbContextOptions<WinTenDbContext> options) : base(options)
{
}
public DbSet<Employee> Employees { get; set; }
public DbSet<Department> Departments { get; set; }
public DbSet<Appointment> Appointments { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Employee>()
.HasKey(e => e.EmployeeID);
modelBuilder.Entity<Employee>()
.Property(e => e.FirstName)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<Employee>()
.Property(e => e.LastName)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<Department>()
.HasKey(d => d.DepartmentID);
modelBuilder.Entity<Department>()
.Property(d => d.Name)
.HasColumnType("varchar(50)")
.HasMaxLength(50);
modelBuilder.Entity<Appointment>()
.HasKey(a => a.AppointmentID);
modelBuilder.Entity<Appointment>()
.Property(a => a.TimeSlot)
.HasColumnType("varchar(50)")
.HasMaxLength(50);
}
}
EmployeesController
public class EmployeesController : Controller
{
private readonly WinTenDbContext _context;
public EmployeesController(WinTenDbContext context)
{
_context = context;
}
// GET: Employees and their Departments
public async Task<IActionResult> Index()
{
var webAppDbContext = _context.Employees.Include(d => d.Department).Include(a => a.Appointment);
return View(await webAppDbContext.ToListAsync());
}
// GET: Employees/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var employee = await _context.Employees
.SingleOrDefaultAsync(m => m.EmployeeID == id);
if (employee == null)
{
return NotFound();
}
return View(employee);
}
// GET: Employees/Create
public IActionResult Create()
{
var departments = _context.Departments.ToList();
var appointments = _context.Appointments.ToList();
var viewModel = new EmployeeFormVM
{
Departments = departments,
Appointments = appointments
};
return View(viewModel);
}
// POST: Employees/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(EmployeeFormVM employee)
{
if (ModelState.IsValid)
{
var emp = new Employee();
{
emp.FirstName = employee.FirstName;
emp.LastName = employee.LastName;
emp.DepartmentID = employee.DepartmentID;
emp.AppointmentID = employee.AppointmentID;
}
// Query DB to check if Employee exists with same First/Last Name
Employee existingEmployee = await _context.Employees.SingleOrDefaultAsync(m => m.FirstName == employee.FirstName && m.LastName == employee.LastName);
if (existingEmployee != null)
{
// Display Error if duplicate employee
ModelState.AddModelError(string.Empty, "An employee with this name has already registered");
employee.Departments = _context.Departments.ToList();
employee.Appointments = _context.Appointments.ToList();
return View(employee);
}
// Query DB to check if appointment has already been assigned to an employee
Employee existingAppointment = await _context.Employees.SingleOrDefaultAsync(m => m.AppointmentID == employee.AppointmentID);
if (existingAppointment != null)
{
// Display error if the appointment was already chosen
ModelState.AddModelError(string.Empty, "This appointment has already been taken. Please select another timeslot.");
employee.Departments = _context.Departments.ToList();
employee.Appointments = _context.Appointments.ToList();
return View(employee);
}
_context.Add(emp);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(employee);
}
// GET: Employees/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var employeevm = new EmployeeFormVM();
{
Employee employee = await _context.Employees.SingleOrDefaultAsync(m => m.EmployeeID == id);
if (employee == null)
{
return NotFound();
}
employeevm.EmployeeID = employee.EmployeeID;
employeevm.FirstName = employee.FirstName;
employeevm.LastName = employee.LastName;
// Retrieve list of Departments
var departments = _context.Departments.ToList();
employeevm.Departments = departments;
// Set the selected department
employeevm.DepartmentID = employee.DepartmentID;
// Retrieve list of Appointments
var appointments = _context.Appointments.ToList();
employeevm.Appointments = appointments;
// Set the selected department
employeevm.AppointmentID = employee.AppointmentID;
}
return View(employeevm);
}
// POST: Employees/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(EmployeeFormVM vmEdit)
{
if (ModelState.IsValid)
{
Employee employee = _context.Employees.SingleOrDefault(e => e.EmployeeID == vmEdit.EmployeeID);
if (employee == null)
{
return NotFound();
}
employee.FirstName = vmEdit.FirstName;
employee.LastName = vmEdit.LastName;
employee.DepartmentID = vmEdit.DepartmentID;
employee.AppointmentID = vmEdit.AppointmentID;
try
{
_context.Update(employee);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!EmployeeExists(vmEdit.EmployeeID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(vmEdit);
}
// GET: Employees/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var employee = await _context.Employees
.SingleOrDefaultAsync(m => m.EmployeeID == id);
if (employee == null)
{
return NotFound();
}
return View(employee);
}
// POST: Employees/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var employee = await _context.Employees.SingleOrDefaultAsync(m => m.EmployeeID == id);
_context.Employees.Remove(employee);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool EmployeeExists(int id)
{
return _context.Employees.Any(e => e.EmployeeID == id);
}
}
Create View
#using (Html.BeginForm("Create", "Employees"))
{
#Html.ValidationSummary(true, "", new { #class = "validation-summary-errors" })
//#Html.ValidationSummary(true, "", new { #style = "color: #cc0000" })
//#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(e => e.FirstName)
#Html.TextBoxFor(e => e.FirstName, new { #class = "form-control" })
#Html.ValidationMessageFor(e => e.FirstName)
</div>
<div class="form-group">
#Html.LabelFor(e => e.LastName)
#Html.TextBoxFor(e => e.LastName, new { #class = "form-control" })
#Html.ValidationMessageFor(e => e.LastName)
</div>
<div class="form-group">
#Html.LabelFor(d => d.DepartmentID)
#Html.DropDownListFor(d => d.DepartmentID, new SelectList(Model.Departments, "DepartmentID", "Name"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(d => d.DepartmentID)
</div>
<div class="form-group">
#Html.LabelFor(a => a.AppointmentID)
#Html.DropDownListFor(a => a.AppointmentID, new SelectList(Model.Appointments, "AppointmentID", "TimeSlot"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(a => a.AppointmentID)
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
}
Edit View
#using (Html.BeginForm("Edit", "Employees"))
{
<div class="form-group">
#Html.LabelFor(e => e.FirstName)
#Html.TextBoxFor(e => e.FirstName, new { #class = "form-control" })
#Html.ValidationMessageFor(e => e.FirstName)
</div>
<div class="form-group">
#Html.LabelFor(e => e.LastName)
#Html.TextBoxFor(e => e.LastName, new { #class = "form-control" })
#Html.ValidationMessageFor(e => e.LastName)
</div>
<div class="form-group">
#Html.LabelFor(d => d.DepartmentID)
#Html.DropDownListFor(d => d.DepartmentID, new SelectList(Model.Departments, "DepartmentID", "Name"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(d => d.DepartmentID)
</div>
<div class="form-group">
#Html.LabelFor(a => a.AppointmentID)
#Html.DropDownListFor(a => a.AppointmentID, new SelectList(Model.Appointments, "AppointmentID", "TimeSlot"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(a => a.AppointmentID)
</div>
#Html.HiddenFor(e => e.EmployeeID)
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
}
You could use a simple LINQ query like below:
var appointments = _context.Appointments.Include(x=>x.Employees).Where(x=>!x.Em‌​ployees.Any()).ToLis‌​t();
If you need to reuse the code, you could use the repository pattern and extract this code to another class.
Each time you need that data filtered, for example in GET methods, you will need to apply that query.
For POST methods, you might skip it, unless:
You want to do validation. If you suspect the user could have tampered with the input, and somehow provided an invalid ID, then you might want to check against that filtered data again.
You want to manage concurrency - suppose two users requested the page at the same time, and specific appointment slot was available. What if both of those employees selected the same time slot? In this case a check on POST would be helpful, to prevent invalid data

Get Submitted Data From Dropdown in View Model?

I have a people controller for user management and I'm trying to figure out how to get the dropdown choice when the user submits from the edit page. Whenever I hit submit on the page, none of the values from the view model seem to carry through to the post. I can't get the value they chose from the drop down to set the role.
See view model below:
public class PersonViewModel
{
public int PersonId { get; set; }
[Display(Name = "Full Name")]
public string FullName { get; set; }
public string Email { get; set; }
[Display(Name = "Current Role")]
public string SetRole { get; set; }
public List<RoleListViewModel> Roles { get; set; }
}
See controller edit functions below:
// GET: People/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Person person = db.people.Find(id);
if (person == null)
{
return HttpNotFound();
}
PersonViewModel pvm = new PersonViewModel();
List<IdentityRole> roles = adb.Roles.ToList();
var rlvm = new List<RoleListViewModel>();
roles.ForEach(x => rlvm.Add(new RoleListViewModel { RoleId = x.Id, RoleName = x.Name }));
pvm.PersonId = person.PersonId;
pvm.FullName = person.FirstName + " " + person.LastName;
pvm.Email = person.Email;
pvm.Roles = rlvm;
ViewBag.RoleList = new SelectList(rlvm, "RoleName", "RoleName", person.CurrentRole);
return View(pvm);
}
// POST: People/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(PersonViewModel pvm)
{
if (ModelState.IsValid)
{
db.Entry(pvm).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
var usr = new AccountController();
var pers = db.people.Where(x => x.PersonId == pvm.PersonId).FirstOrDefault();
usr.UserManager.AddToRoleAsync(pers.NetId, /* their choice should go here but how? */);
db.SaveChanges();
return View(pvm);
}
Here is the cshtml:
<div class="form-group">
#Html.LabelFor(model => model.Roles, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="form-control-static">
#Html.DropDownList("RoleList", null, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Roles, "", new { #class = "text-danger" })
</div>
</div>
Make a variable in your View Model to store the selected value and then in the view use
#Html.DropDownListFor(m => m.SelectedRoleVariable, RolesSelectList, new { #class = "form-control" });

HttpPostedFileBase to varbinary(max)

I have just tried a lot of things that I found but at the end nothing successfull.
First I have the next code that just do the things ok but dont save the image.
What should I do to save an image into a varbinarymax? and how to show them to the view next?
view:
<div class="form-group">
#Html.LabelFor(model => model.Logo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#*#Html.EditorFor(model => model.Logo, new { htmlAttributes = new { #class = "form-control" } })*#
#Html.TextBoxFor(model => model.Logo, new { type = "file" })
#Html.ValidationMessageFor(model => model.Logo, "", new { #class = "text-danger" })
</div>
</div>
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Id,Name,Address,Description,Mail,Phone,Small_Description")] School school)
{
if (ModelState.IsValid)
{
db.School.Add(school);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(school);
}
Model:
public partial class School
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public School()
{
this.Product = new HashSet<Product>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Description { get; set; }
public string Mail { get; set; }
public int? Phone { get; set; }
public byte[] Logo { get; set; }
public string Small_Description { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Product> Product { get; set; }
}
Change View First to This:
#using (Html.BeginForm("Create", "Schole", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
#Html.LabelFor(model => model.Logo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.Logo, new { type = "file" })
<input type="submit" value="submit" />
</div>
</div>
}
Change Action To This:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Id,Name,Address,Description,Mail,Phone,Small_Description")] School school, HttpPostedFileBase Logo)
{
if (ModelState.IsValid)
{
using (var memoryStream = new MemoryStream())
{
Logo.InputStream.CopyTo(memoryStream);
school.Logo = memoryStream.ToArray();
}
db.School.Add(school);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(school);
}
}
Now This Logo Save It.
As you don't have posted complete form, here is complete code to upload image and save into DB.
you form must have enctype property.
#using (Html.BeginForm("Index","Home",FormMethod.Post, new{ enctype = "multipart/form-data" }))
{
//your other code
<input type="file" name="logo" />
<input type="submit" value="Save" />
}
And inside your action.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Id,Name,Address,Description,Mail,Phone,Small_Description")] School school)
{
if (ModelState.IsValid)
{
byte[] fileData = null;
using (var binaryReader = new BinaryReader(Request.Files["logo"].InputStream))
{
fileData = binaryReader.ReadBytes(Request.Files["logo"].ContentLength);
}
school.Logo=fileData;
db.School.Add(school);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(school);
}
It will save file in your Db.

Categories

Resources