Related
So I have some custom validation implemented to prevent similar records being entered into the db. The only problem I have is that it is not presenting the user an error/validation message but rather an error page.
Where am I going wrong? Or how do I correctly implement this?
Validation:
public class ValidSimilarRequests : ValidationAttribute
{
private LotusWorksEntities db = new LotusWorksEntities();
protected override ValidationResult
IsValid(object value, ValidationContext validationContext)
{
var model = (Models.HolidayRequestForm)validationContext.ObjectInstance;
int empID = Convert.ToInt32(model.EmployeeID);
DateTime _startdate = Convert.ToDateTime(model.StartDate);
DateTime _finishdate = Convert.ToDateTime(model.FinishDate);
var holidayexist = db.HolidayRequestForms.Any( x => x.EmployeeID==empID && x.StartDate <= _startdate && x.FinishDate >= _finishdate );
if (holidayexist)
{
return new ValidationResult
("A holiday Request for this date range has already been requested");
}
else
{
return ValidationResult.Success;
}
}
}
Model:
public partial class HolidayRequestForm
{
public int RequestID { get; set; }
[ValidSimilarRequests(ErrorMessage =
"A holiday Request for this date range has already been requested")]
public int EmployeeID { get; set; }
[ValidSameWeek(ErrorMessage =
"Holiday Request Must be made on a weekly Period")]
[DisplayFormat(DataFormatString = "{0:dd/MMM/yy}", ApplyFormatInEditMode = true)]
public System.DateTime StartDate { get; set; }
[ValidStartFinishDate(ErrorMessage =
"Finish Date can not be Greater than Start date.")]
[DisplayFormat(DataFormatString = "{0:dd/MMM/yy}", ApplyFormatInEditMode = true)]
public System.DateTime FinishDate { get; set; }
[Range(0.0001, int.MaxValue, ErrorMessage = "Hours Requested must be greater than zero. ")]
public decimal HoursTaken { get; set; }
public string Comments { get; set; }
public int YearCreated { get; set; }
public int MonthCreated { get; set; }
public int DayCreated { get; set; }
public Nullable<int> YearOfHoliday { get; set; }
public Nullable<bool> Approved { get; set; }
public string SubmittedBy { get; set; }
public string ApprovedBy { get; set; }
public Nullable<int> WorkWeek { get; set; }
public Nullable<int> MonthOfHoliday { get; set; }
public virtual Employee Employee { get; set; }
}
The Error Page shows:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Controller:
[Authorize(Roles = "Admin,User,SuperUser")]
public ActionResult Create()
{
ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "FullName");
return View();
string name = Session["Name"].ToString();
var EmployeeIDCatch = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.EmployeeID);
}
// POST: HolidayRequestForms/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 ActionResult Create([Bind(Include = "RequestID,StartDate,FinishDate,HoursTaken,Comments,YearCreated,MonthCreated,DayCreated,YearOfHoliday,Approved,SubmittedBy,ApprovedBy")] HolidayRequestForm holidayRequestForm)
{
if (ModelState.IsValid)
{
if (Session["Name"] == null)
{
TempData["msg"] = "Your Session Expired - Please Login";
return RedirectToAction("Login", "Account");
}
string name = Session["Name"].ToString();
var employeeID = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.EmployeeID).FirstOrDefault();
holidayRequestForm.EmployeeID = employeeID;
var submittedby = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.Email).FirstOrDefault();
holidayRequestForm.SubmittedBy = submittedby;
//Saves changes and begins Email Actions
db.HolidayRequestForms.Add(holidayRequestForm);
db.SaveChanges();
SendMailToAreaManager();
SendMailToManager();
SendMailToAdmin();
return RedirectToAction("Index", "Calendar");
}
ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "FullName", holidayRequestForm.EmployeeID);
return View(holidayRequestForm);
}
VIEW:
#model HolidayTracker.Models.HolidayRequestForm
<div>
<div class="col-md-12">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h2 align="center">Holiday Request Form</h2>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.StartDate, "Start Date", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StartDate, "Start Date", new { htmlAttributes = new { #class = "form-control", #style = "width:400px", autocomplete = "off" } })
#Html.ValidationMessageFor(model => model.StartDate, "", new { #class = "text-warning" })
<p id="warning" style="color:orange"></p>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FinishDate, "Finish Date", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FinishDate, new { htmlAttributes = new { #class = "form-control",#style = "width:400px", autocomplete = "off" } })
#Html.ValidationMessageFor(model => model.FinishDate, "", new { #class = "text-danger" })
<p id="warningFD" style="color:orange"></p>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.HoursTaken, "Hours Requested", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.HoursTaken, new { htmlAttributes = new { #class = "form-control", #style = "width:400px" } })
#Html.ValidationMessageFor(model => model.HoursTaken, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comments, htmlAttributes: new { #class = "control-label col-md-2"})
<div class="col-md-10">
#Html.TextAreaFor(
model => model.Comments,
new { placeholder = "Enter Dates and how many Hours per Date Here. ", style = "width: 400px; height: 200px;" })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-warning" />
</div>
</div>
}
</div>
</div>
</div>
I previously reveived some help here but some problems with the "Edit" arouse now. Currently stuck at HttpGet, HttpPost is yet to come.
In short, whenever I click on an existing item to edit, instead of the expected values, it returns an empty form, as seen here. (You might think that the reason for this is because I use the same exact view for Create and Edit but unfortunately this isn't, even when I used to separate ones, had the same result.)
Town.cs
using System.Collections.Generic;
namespace City.Models
{
public class Town
{
public Town()
{
Streets = new List<Street>();
}
public int TownId { get; set; }
public string TownName { get; set; }
public virtual ICollection<Street> Streets { get; set; }
}
}
Street.cs
using System.Collections.Generic;
namespace City.Models
{
public class Street
{
public Street()
{
Houses = new List<House>();
}
public int StreetId { get; set; }
public string StreetName { get; set; }
public virtual ICollection<House> Houses { get; set; }
}
}
House.cs
using System.Collections.Generic;
namespace City.Models
{
public class House
{
public House()
{
Floors = new List<Floor>();
}
public int HouseId { get; set; }
public string HouseName { get; set; }
public ICollection<Floor> Floors { get; set; }
}
}
Floor.cs
using System.Collections.Generic;
namespace City.Models
{
public class Floor
{
public Floor()
{
FireExtinguishers = new List<FireExtinguisher>();
}
public int FloorId { get; set; }
public int FloorNumber { get; set; }
public virtual ICollection<FireExtinguisher> FireExtinguishers { get; set; }
}
}
FireExtinguisher.cs
using System.ComponentModel;
namespace City.Models
{
public class FireExtinguisher
{
public int FireExtinguisherId { get; set; }
[DisplayName("Fire Extinguisher")]
public string FireExtinguisherName { get; set; }
public int FloorId { get; set; }
public int HouseId { get; set; }
public int StreetId { get; set; }
public int TownId { get; set; }
public Floor Floor { get; set; }
public House House { get; set; }
public Street Street { get; set; }
public Town Town { get; set; }
}
}
MyViewModel.cs
using System.Collections.Generic;
namespace City.Models
{
public class MyViewModel
{
public IEnumerable<Town> TownId { get; set; }
public IEnumerable<Street> StreetId { get; set; }
public IEnumerable<House> HouseId { get; set; }
public IEnumerable<Floor> FloorId { get; set; }
public FireExtinguisher FireExtinguisher { get; set; }
public string FireExtinguisherName { get; set; }
}
}
Create/Edit view
#model City.Models.MyViewModel
<h2>Add new or edit existing FE</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-md-12">
<div class="form-group">
#Html.LabelFor(model => model.TownId, "Town", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.TownId, new SelectList(Model.TownId, "TownId", "TownName"), "Choose Town", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TownId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StreetId, "Street", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.StreetId, new SelectList(Model.StreetId, "StreetId", "StreetName"), "Choose Street", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.StreetId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.HouseId, "House", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.HouseId, new SelectList(Model.HouseId, "HouseId", "HouseName"), "Choose House", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.HouseId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FloorId, "Floor", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.FloorId, new SelectList(Model.FloorId, "FloorId", "FloorNumber"), "Choose Floor", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.FloorId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FireExtinguisherName, "Fire Extinguisher", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.FireExtinguisherName, new { #class = "form-control", Value = "" })
#Html.ValidationMessageFor(model => model.FireExtinguisherName, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div>
<div>
<input type="submit" value="Do it" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Homecontroller.cs
using System;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using City.Models;
namespace City.Controllers
{
public class HomeController : Controller
{
private ApplicationDbContext db;
private MyViewModel viewModel;
public HomeController()
{
db = new ApplicationDbContext();
var town = db.Towns.ToList();
var street = db.Streets.ToList();
var house = db.Houses.ToList();
var floor = db.Floors.ToList();
viewModel = new MyViewModel()
{
TownId = town,
StreetId = street,
HouseId = house,
FloorId = floor
};
}
public ActionResult Index()
{
return View(db.FireExtinguishers.ToList());
}
[HttpGet]
public ActionResult Create()
{
return View(viewModel);
}
[HttpPost]
public ActionResult Create(FireExtinguisher fe)
{
if (ModelState.IsValid)
{
db.FireExtinguishers.Add(fe);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel);
}
[HttpGet]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var fe = db.FireExtinguishers.Find(id);
var town = db.Towns.ToList();
var street = db.Streets.ToList();
var house = db.Houses.ToList();
var floor = db.Floors.ToList();
viewModel = new MyViewModel()
{
FireExtinguisher = fe,
TownId = town,
StreetId = street,
HouseId = house,
FloorId = floor
};
return View("Create", viewModel);
}
[HttpPost]
public ActionResult Edit()
{
throw new NotImplementedException();
}
}
}
Any help would be appreciated, thank you
Personally I like to use View- and Post-Models for that as a clear statement, what is send to the View (ViewModel) and what is send back via Post. As a naming convention the name of the model class Takes the controller name and the action name.
I start with the PostModel, which would be in your case
public class HomeEditPostModel
{
[Required]
[MaxLength(50)]
public string Name { get; set; }
[Required]
public int TownId { get; set; }
[Required]
public int StreetId { get; set; }
[Required]
public int HouseId { get; set; }
[Required]
public int FloorId { get; set; }
}
Now for the view we need some collections for the dropdown fields, where we can select from
public class SelectionItem<TKey>
{
public TKey Key { get; set; }
public string DisplayName { get; set; }
}
public class HomeEditViewModel : HomeEditPostModel
{
public IEnumerable<SelectionItem<int>> Town { get; set; }
public IEnumerable<SelectionItem<int>> Street { get; set; }
public IEnumerable<SelectionItem<int>> House { get; set; }
public IEnumerable<SelectionItem<int>> Floor { get; set; }
}
Now the view
#model WebApplication6.Models.HomeEditViewModel
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>HomeEditSubmitModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TownId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.TownId, new SelectList(Model.Town, "Key", "DisplayName"), "Choose Town", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TownId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StreetId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.StreetId, new SelectList(Model.Street, "Key", "DisplayName"), "Choose Street", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.StreetId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.HouseId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.HouseId, new SelectList(Model.House, "Key", "DisplayName"), "Choose House", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.HouseId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FloorId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.FloorId, new SelectList(Model.Floor, "Key", "DisplayName"), "Choose Floor", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.FloorId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
and finally the controller (only relevant parts)
public class HomeController : Controller
{
[HttpGet]
public ActionResult Edit(int id)
{
// just some fake data for demonstration
var model = new HomeEditViewModel
{
Name = "Name",
Floor = Enumerable.Range(1, 10).Select(e => new SelectionItem<int> { Key = e, DisplayName = $"Floor {e}" }),
Street = Enumerable.Range(1, 10).Select(e => new SelectionItem<int> { Key = e, DisplayName = $"Street {e}" }),
House = Enumerable.Range(1, 10).Select(e => new SelectionItem<int> { Key = e, DisplayName = $"House {e}" }),
Town = Enumerable.Range(1, 10).Select(e => new SelectionItem<int> { Key = e, DisplayName = $"Town {e}" }),
FloorId = 3,
StreetId = 4,
HouseId = 5,
TownId = 6,
};
return View(model);
}
[HttpPost]
public ActionResult Edit(int id, HomeEditPostModel model)
{
// needs to save the data here
return RedirectToAction(nameof(Index));
}
}
I am working on small ticket system for operations maintenance services comp.
Customer open a ticket and gives general information like location,
category description etc.
After technician fix the problem he must give sum details of the
problem from predefined set, use later for statistical reports.
My problem the repair method unable to post updated values to database plus nothing added to Defects_List table.
Note: I used this tutorial as guide
Models:
public partial class Tickets
{
public Tickets()
{
this.DefectsList = new HashSet<Defects_List>();
}
[Key]
[Display(Name = "Ticket Id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Ticket_Id { get; set; }
[Display(Name = "Project")]
public int Project_Id { get; set; }
[Display(Name = "Issue Date")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime Issue_Date { get; set; }
[Display(Name = "Category")]
[DisplayFormat(NullDisplayText = "[Not set]")]
public int Category_Id { get; set; }
//Other Properties Removed for clarity
public virtual Business_Category businessCategories { get; set; }
public virtual ICollection<Defects_List> DefectsList { get; set; }
}
public partial class Business_Category
{
public Business_Categories()
{
this.Tickets = new HashSet<Tickets>();
this.Malfunctions = new HashSet<Malfunctions>();
}
[Key]
[Display(Name="Category Id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Category_Id { get; set; }
[Display(Name = "Name (eng)")]
[StringLength(60, ErrorMessage = "Name cannot be longer than 60 characters.")]
public string Category_Name { get; set; }
public virtual ICollection<Tickets> Tickets { get; set; }
public virtual ICollection<Manufacturers> Manufacturers { get; set; }
public virtual ICollection<Malfunctions> Malfunctions { get; set; }
}
public partial class Defects_List
{
[Key, Column(Order = 0)]
[Display(Name = "Ticket Id")]
public int Ticket_Id { get; set; }
[Key, Column(Order = 1)]
[Display(Name = "Malfunction Id")]
public int Malfunction_Id { get; set; }
[StringLength(125, ErrorMessage = "Other cannot be longer than 125 characters.")]
public string Other { get; set; }
public virtual ICollection<Tickets> Tickets { get; set; }
public virtual Malfunctions Malfunctions { get; set; }
}
Controller:
// GET: /Tickets/Edit/5
public ActionResult Repair(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var tickets = db.nt_Tickets
.Include(t => t.DefectsList).Where(t => t.Ticket_Id == id)
.Single();
if (tickets == null)
{
return HttpNotFound();
}
PopulateSelectedDefects(tickets);
//Other codes Removed for clarity
return View(tickets);
}
private void PopulateSelectedDefects(nt_Tickets Tickets)
{
int categoryId;
if (Tickets.Category_Id == 2)
categoryId = 1;
else categoryId = Tickets.Category_Id;
var allDefects = (from m in db.sys_Malfunctions
where m.Category_Id == categoryId
select m).ToList();
var ticketDefects = new HashSet<int>(Tickets.DefectsList.Select(t => t.Malfunction_Id));
var viewModel = new List<TicketDefectsViewModel>();
foreach (var defect in allDefects)
{
viewModel.Add(new TicketDefectsViewModel
{
Malfunction_Id = defect.Malfunction_Id,
Malfunction_Name_e = defect.Malfunction_Name_e,
IsSelected = ticketDefects.Contains(defect.Malfunction_Id)
});
}
ViewBag.Defects = viewModel;
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Repair(int? id, string[] selectedDefects)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var ticketToUpdate = db.nt_Tickets
.Include(i => i.DefectsList)
.Where(i => i.Ticket_Id == id)
.Single();
if (TryUpdateModel(ticketToUpdate, "",
new string[] { Ticket_Id,Project_Id,Category_Id,Subject,Workshop_Id,Requested_By,Requestor_Mobile, Requestor_eMail,Location_Id,Ticket_Status,Periority_Id,Assigned_To,Description,Issue_Date,Created_By,Created_Date,Updated_By,Updated_Date" }))
{
ticketToUpdate.Updated_By = User.Identity.Name;
ticketToUpdate.Updated_Date = DateTime.UtcNow;
db.Entry(ticketToUpdate).State = EntityState.Modified;
SetTicketDefects(selectedDefects, ticketToUpdate);
try
{
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DbEntityValidationException dbEx)
{
Exception raise = dbEx;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
string message = string.Format("{0}:{1}",
validationErrors.Entry.Entity.ToString(),
validationError.ErrorMessage);
if (!string.IsNullOrEmpty(message))
ViewBag.errorMessage = message;
}
return View("Error");
}
throw raise;
}
}
PopulateSelectedDefects(ticketToUpdate);
return View("Index");
}
private void SetTicketDefects(string[] selectedDefects, Tickets ticketToUpdate)
{
if (selectedDefects == null)
{
ticketToUpdate.DefectsList = new List<Defects_List>();
return;
}
var selectedDefectsHS = new HashSet<string>(selectedDefects);
var tcketDefects = new HashSet<int>
(ticketToUpdate.DefectsList.Select(c => c.Ticket_Id));
foreach (var defect in db.DefectsLists)
{
if (selectedDefectsHS.Contains(defect.Malfunction_Id.ToString()))
{
if (!tcketDefects.Contains(defect.Malfunction_Id))
{
ticketToUpdate.DefectsList.Add(defect);
}
}
else
{
if (tcketDefects.Contains(defect.Malfunction_Id))
{
ticketToUpdate.DefectsList.Remove(defect);
}
}
}
}
db.DefectsLists here [foreach (var defect in db.DefectsLists)] always empty.
Repair View:
#using (Html.BeginForm("Repair", "Tickets", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
#*#using (Html.BeginForm())*#
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Ticket_Id)
#Html.HiddenFor(model => model.Issue_Date)
#Html.HiddenFor(model => model.Created_By)
#Html.HiddenFor(model => model.Project_Id)
#Html.HiddenFor(model => model.Created_Date)
<div class="form-group">
#Html.Label("Ticket_Id", new { #class = "control-label col-md-2" })
<div class="col-md-1 " style="margin-top:7px">
#Html.DisplayFor(model => model.Ticket_Id)
</div>
#Html.LabelFor(model => model.Issue_Date, new { #class = "control-label col-md-2" })
<div class="col-md-2" style="margin-top:7px">
#Html.DisplayFor(model => model.Issue_Date, new { #class = "form-control" })
</div>
#Html.LabelFor(model => model.Category_Id, new { #class = "control-label col-md-2" })
<div class="col-md-3" style="margin-top:7px">
#Html.DropDownList("Category_Id", null, new { #class = "form-control", #disabled = "disabled" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Subject, new { #class = "control-label col-md-2" })
<div class="col-md-10" style="margin-top:7px">
#Html.DisplayFor(model => model.Subject, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, new { #class = "control-label col-md-2" })
<div class="col-md-10" style="margin-top:7px">
#Html.DisplayFor(model => model.Description, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Requested_By, new { #class = "control-label col-md-2" })
<div class="col-md-5" style="margin-top:7px">
#Html.DisplayFor(model => model.Requested_By, new { #class = "form-control" })
</div>
#Html.LabelFor(model => model.Requestor_Mobile, new { #class = "control-label col-md-2" })
<div class="col-md-3" style="margin-top:7px">
#Html.DisplayFor(model => model.Requestor_Mobile, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Requestor_eMail, new { #class = "control-label col-md-2" })
<div class="col-md-10" style="margin-top:7px">
#Html.DisplayFor(model => model.Requestor_eMail, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Ticket_Status, new { #class = "control-label col-md-2" })
<div class="col-md-4" style="margin-top:7px">
#Html.EnumDropDownListFor(model => model.Ticket_Status, new { #class = "form-control" })
</div>
#Html.LabelFor(model => model.Periority_Id, new { #class = "control-label col-md-2" })
<div class="col-md-4" style="margin-top:7px">
#Html.EnumDropDownListFor(model => model.Periority_Id, new { #class = "form-control", #disabled = "disabled" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Location_Id, new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.DropDownList("Location_Id", null, new { #class = "form-control", #disabled = "disabled" })
#Html.ValidationMessageFor(model => model.Location_Id)
</div>
#Html.LabelFor(model => model.Assigned_To, new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.DropDownList("Assigned_To", null, new { #class = "form-control", #disabled = "disabled" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.Label("Defects")
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<table class="table table-hover">
<tr>
#{
int cnt = 0;
List<MaintCare.ViewModels.TicketDefectsViewModel> defects = ViewBag.Defects;
foreach (var defect in defects)
{
if (cnt++ % 3 == 0)
{
#:</tr><tr>
}
#:<td>
<input type="checkbox"
name="selectedDefects"
value="#defect.Malfunction_Id"
#(Html.Raw(defect.IsSelected ? "checked=\"checked\"" : "")) />
#defect.Malfunction_Name_e
#:</td>
}
#:</tr>
}
</table>
</div>
</div>
<br />
<div class="form-group">
<div class="col-md-2">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
I am trying to upload an image in mvc however it keeps returning null.
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PostRollOutForm([Bind(Include = "TankSerNo,NozzleSerNo,NozzleLocationDescript,NozzleIdentifier,NozzleFunction,NozzleType,NozzleDiameterorHeight,NozzleWidth,NozzleLocation,NozzleHeight,NozzleWeldSize,NozzleThickness,NozzleComments,RepadShape,RepadHeight,RepadWidth,RepadWeldSize,RepadThickness,TelTale,WeldSpacetoCornerWeld,WeldSpacetoVerticalWeld,WeldSpacetoAdjacentNozzle,WeldSpacetoHorizontalWeld,WeldDetail,CoverThickness,LengthToFlange,LenghtToCtrofValve,CenterLineorLowerHeight,DrawCircleorNot,CornerRadius,Dimension,Label,NozzleThicknessT,NozzleThicknessR,NozzleThicknessB,NozzleThicknessL,Photo")] RollOutViewModel rollout, HttpPostedFileBase uploadedfile, string FailURL)
{
if (ModelState.IsValid)
{
//upload image attempt 1
if(uploadedfile != null) {
RollOutFileUploadService service = new RollOutFileUploadService();
service.SaveFileDetails(uploadedfile, rollout.NozzleSerNo);
}
//attempt 2
else if (rollout.Photo != null)
{
RollOutFileUploadService service = new RollOutFileUploadService();
service.SaveFileDetails(uploadedfile, rollout.NozzleSerNo);
}
//form fields
ShellRollOut result = new ShellRollOut();
result.TankSerNo = rollout.TankSerNo;
result.NozzleSerNo = rollout.NozzleSerNo;
result.NozzleLocationDescript = rollout.NozzleLocationDescript;
result.NozzleIdentifier = rollout.NozzleIdentifier;
result.NozzleFunction = rollout.NozzleFunction;
result.NozzleType = rollout.NozzleType;
result.NozzleDiameterorHeight = rollout.NozzleDiameterorHeight;
result.NozzleWidth = rollout.NozzleWidth;
result.NozzleLocation = rollout.NozzleLocation;
result.NozzleHeight = rollout.NozzleHeight;
result.NozzleWeldSize = rollout.NozzleWeldSize;
result.NozzleThickness = rollout.NozzleThickness;
result.NozzleComments = rollout.NozzleComments;
result.RepadShape = rollout.RepadShape;
result.RepadHeight = rollout.RepadHeight;
result.RepadWidth = rollout.RepadWidth;
result.RepadWeldSize = rollout.RepadWeldSize;
result.RepadThickness = rollout.RepadThickness;
result.TelTale = rollout.TelTale;
result.WeldSpacetoCornerWeld = rollout.WeldSpacetoCornerWeld;
result.WeldSpacetoVerticalWeld = rollout.WeldSpacetoVerticalWeld;
result.WeldSpacetoAdjacentNozzle = rollout.WeldSpacetoAdjacentNozzle;
result.WeldSpacetoHorizontalWeld = rollout.WeldSpacetoHorizontalWeld;
result.CoverThickness = rollout.WeldSpacetoHorizontalWeld;
result.WeldDetail = rollout.WeldDetail;
result.LengthToFlange = rollout.LengthToFlange;
result.LenghtToCtrofValve = rollout.LenghtToCtrofValve;
result.CenterLineorLowerHeight = rollout.CenterLineorLowerHeight;
result.DrawCircleorNot = rollout.DrawCircleorNot;
result.CornerRadius = rollout.CornerRadius;
result.Dimension = rollout.Dimension;
result.Label = rollout.Label;
result.NozzleThicknessT = rollout.NozzleThicknessT;
result.NozzleThicknessR = rollout.NozzleThicknessR;
result.NozzleThicknessB = rollout.NozzleThicknessB;
result.NozzleThicknessL = rollout.NozzleThicknessL;
result.Tank = rollout.Tank;
db.ShellRollOuts.Add(result);
db.SaveChanges();
string url = Url.Action("ShellRollOut", new { TankSerNo = rollout.TankSerNo });
return Json(new { success = true, url = url }, JsonRequestBehavior.AllowGet);
}
return PartialView(FailURL, rollout);
}
View Model:
public class RollOutViewModel
{
public Nullable<int> TankSerNo { get; set; }
public int NozzleSerNo { get; set; }
public string NozzleLocationDescript { get; set; }
public string NozzleIdentifier { get; set; }
public string NozzleFunction { get; set; }
public string NozzleType { get; set; }
public Nullable<float> NozzleDiameterorHeight { get; set; }
public Nullable<float> NozzleWidth { get; set; }
public Nullable<float> NozzleLocation { get; set; }
public Nullable<float> NozzleHeight { get; set; }
public Nullable<float> NozzleWeldSize { get; set; }
public Nullable<float> NozzleThickness { get; set; }
public string NozzleComments { get; set; }
public string RepadShape { get; set; }
public Nullable<float> RepadHeight { get; set; }
public Nullable<float> RepadWidth { get; set; }
public Nullable<float> RepadWeldSize { get; set; }
public Nullable<float> RepadThickness { get; set; }
public string TelTale { get; set; }
public Nullable<float> WeldSpacetoCornerWeld { get; set; }
public Nullable<float> WeldSpacetoVerticalWeld { get; set; }
public Nullable<float> WeldSpacetoAdjacentNozzle { get; set; }
public Nullable<float> WeldSpacetoHorizontalWeld { get; set; }
public string WeldDetail { get; set; }
public Nullable<float> CoverThickness { get; set; }
public string LengthToFlange { get; set; }
public string LenghtToCtrofValve { get; set; }
public string CenterLineorLowerHeight { get; set; }
public string DrawCircleorNot { get; set; }
public Nullable<float> CornerRadius { get; set; }
public string Dimension { get; set; }
public string Label { get; set; }
public Nullable<float> NozzleThicknessT { get; set; }
public Nullable<float> NozzleThicknessR { get; set; }
public Nullable<float> NozzleThicknessB { get; set; }
public Nullable<float> NozzleThicknessL { get; set; }
public HttpPostedFileBase Photo { get; set; }
public virtual Tank Tank { get; set; }
}
View:
#using (Html.BeginForm("PostRollOutForm", "Tanks", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="modal-body">
<div class="form-horizontal">
#Html.HiddenFor(x => x.NozzleIdentifier, new { #Value = "" })
#Html.HiddenFor(x => x.TankSerNo)
#Html.HiddenFor(x => x.Tank)
#Html.HiddenFor(x => x.NozzleSerNo)
<h4>Nozzle Data</h4>
<div class="form-group">
#Html.LabelFor(model => model.NozzleFunction, "Nozzle Function", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownListFor(model => model.NozzleFunction, new List<SelectListItem>
{
new SelectListItem { Text = "Spiral Stairway", Value = "Spiral Stairway", Selected = true},
new SelectListItem { Text = "Cat Walk", Value = "Cat Walk"},
new SelectListItem { Text = "Vertical Ladder", Value = "Vertical Ladder"},
new SelectListItem { Text = "Platform", Value = "Platform"},
new SelectListItem { Text = "Radial Stairway", Value = "Radial Stairway"},
},
new { #class = "form-control " })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.NozzleDiameterorHeight, "Hand Rail Height", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.NozzleDiameterorHeight, new { htmlAttributes = new { #id = "HandRailHeight", #class = "form-control " } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.NozzleHeight, "Height Step or Rise", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.NozzleHeight, new { htmlAttributes = new { #id = "HeightStep", #class = "form-control " } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.NozzleWidth, "Width of Run", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.NozzleWidth, new { htmlAttributes = new { #id = "WidthRun", #class = "form-control " } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RepadHeight, "Last Step", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.RepadHeight, new { htmlAttributes = new { #id = "RepadHeight", #class = "form-control " } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RepadWidth, "Cage Height", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.RepadWidth, new { htmlAttributes = new { #id = "RepadWidth", #class = "form-control " } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RepadShape, "Shape of Access", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownListFor(model => model.RepadShape, new List<SelectListItem>
{
new SelectListItem { Text = "SW+", Value = "SW+", Selected = true},
new SelectListItem { Text = "SW-", Value = "SW-"},
new SelectListItem { Text = "CATWALK", Value = "CATWALK"},
new SelectListItem { Text = "CAGED LADDER", Value = "CAGED LADDER"},
new SelectListItem { Text = "LADDER", Value = "LADDER"},
},
new { #class = "form-control " })
</div>
</div>
<h4>Miscellaneous</h4>
<div class="form-group">
#Html.LabelFor(model => model.DrawCircleorNot, "Draw Pipe Circle?", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownListFor(model => model.DrawCircleorNot, new List<SelectListItem>
{
new SelectListItem { Text = "CIRCLE", Value = "CIRCLE"},
new SelectListItem { Text = "NO CIRCLE", Value = "NO CIRCLE", Selected = true},
},
new { #class = "form-control " })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Label, "Label?", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.DropDownListFor(model => model.Label, new List<SelectListItem>
{
new SelectListItem { Text = "LABEL", Value = "LABEL", Selected = true},
new SelectListItem { Text = "NO LABEL", Value = "NO LABEL"},
},
new { #class = "form-control " })
</div>
</div>
<hr />
<div class="form-group">
#Html.Label("Image of Shell Appurtenance", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.TextBoxFor(a=> a.Photo, new { type = "file", accept = "image/*", capture = "camera", #class = "btn btn-default btn-sm" })
<input name="uploadefile" type="file" accept="image/*" capture />
</div>
</div>
</div>
#Html.HiddenFor(h => h.Tank.Height, new { #id = "TankHeight" })
</div>
As far as I can see the naming conventions should be correct for the posted file so I'm not sure why it is still returning null. Any help or advice would be greatly appreciated!
The method parameter name should match with the input name. In your code, both are not same.
So change the razor code to
<input name="uploadedfile" type="file"/>
When I submit my form, the values are not being bound to the view model. I can't see what I'm doing wrong. Does anyone see something in my code I'm missing.
Here's a portion of the View:
#model FacilitiesCostIndex.ViewModels.AddAsset.TheViewModel
<div id="addAssetForm-div">
#using (Html.BeginForm("Submit", "AddAsset", FormMethod.Post, new { id = "AddAssetForm" }))
{
<span class="formTitle">#ViewBag.Title</span><br />
<fieldset id="topRow">
<legend></legend>
<!--Location-->
<span id="location" class="notes">- Location -</span><br />
<!--Site-->
<span id="site-span">
#Html.LabelFor(model => model.SiteId, new { #class = "formLabel" })
#Html.DropDownListFor(model => model.SiteId, Model.SiteItems, new { id = "siteDrpDwn", #class = "formDropDown" })
#Html.ValidationMessageFor(model => model.SiteId, string.Empty, new { id = "siteVldMsg", #class = "formValidationMessage" })
</span>
<!--Floor-->
<span id="floor-span">
#Html.LabelFor(model => model.FloorId, new { #class = "formLabel" })
<span id="floorDrpDwnContainer" data-populateurl="#Url.Action("PopulateFloorDrpDwn", "AddAsset")" data-unpopulateurl="#Url.Action("UnpopulateFloorDrpDwn", "AddAsset")">
#{Html.RenderPartial("AddAsset/UnpopulatedFloorDrpDwn", new FacilitiesCostIndex.ViewModels.AddAsset.FloorDrpDwnViewModel());}
</span>
#Html.ValidationMessageFor(model => model.FloorId, string.Empty, new { id = "floorVldMsg", #class = "formValidationMessage" })
</span>
<!--Zone-->
<span id="zone-span">
#Html.LabelFor(model => model.ZoneId, new { #class = "formLabel" })
<span id="zoneDrpDwnContainer" data-populateurl="#Url.Action("PopulateZoneDrpDwn", "AddAsset")" data-unpopulateurl="#Url.Action("UnpopulateZoneDrpDwn", "AddAsset")">
#{Html.RenderPartial("AddAsset/UnpopulatedZoneDrpDwn", new FacilitiesCostIndex.ViewModels.AddAsset.ZoneDrpDwnViewModel());}
</span>
#Html.ValidationMessageFor(model => model.ZoneId, string.Empty, new { id = "zoneVldMsg", #class = "formValidationMessage" })
</span><br />
</fieldset>
<fieldset id="leftColumn">
<legend></legend>
<!--Install Date-->
<div id="installDate-div" class="leftColumnItem">
#Html.LabelFor(model => model.InstallDate, new { id="installDateLbl" }) <br />
#Html.TextBoxFor(model => model.InstallDate, new { id="installDateTxt" })
</div>
<!--Name-->
<div id="assetName-div" class="leftColumnItem">
#Html.LabelFor(model => model.AssetName, new { #class="formLabel" }) <br />
#Html.TextBoxFor(model => model.AssetName, new { id="assetNameTxt", #class = "formTextbox" })
</div>
<!--Asset Number-->
<div id="assetNumber-div" class="leftColumnItem">
#Html.LabelFor(model => model.AssetNumber, new { #class="formLabel" }) <br />
#Html.TextBoxFor(model => model.AssetNumber, new { id="assetNumberTxt", #class = "formTextbox" })
</div>
<!--Description-->
<div id="description-div" class="leftColumnItem">
#Html.LabelFor(model => model.Description, new { #class="formLabel" }) <br />
#Html.TextBoxFor(model => model.Description, new { id="descriptionTxt", #class = "formTextbox" })
</div>
<!--Group-->
<div id="group-div" class="leftColumnItem">
#Html.LabelFor(model => model.GroupId, new { #class = "formLabel" }) <br />
#Html.DropDownListFor(model => model.GroupId, Model.GroupItems, new { id = "groupDrpDwn", #class = "formDropDown" })
#Html.ValidationMessageFor(model => model.GroupId, string.Empty, new { id = "groupVldMsg", #class = "formValidationMessage" })
</div>
Here's a portion of the ViewModel:
public class TheViewModel
{
[Display(Name = "Site")]
public int SiteId { get; set; }
public IEnumerable<SelectListItem> SiteItems { get; private set; }
[Display(Name = "Floor")]
[Required(ErrorMessage = "Please select a Floor.")]
public int FloorId { get; set; }
[Display(Name = "Zone")]
[Required(ErrorMessage = "Please select a Zone.")]
public int ZoneId { get; set; }
[Display(Name = "Name")]
[Required(ErrorMessage = "Please enter an Asset Name.")]
public string AssetName { get; set; }
[Display(Name = "Asset Number")]
[Required(ErrorMessage = "Please enter an Asset Number.")]
public string AssetNumber { get; set; }
[Display(Name = "Description")]
public string Description { get; set; }
[Display(Name = "INSTALL DATE")]
[Required(ErrorMessage = "Please enter an install date.")]
public DateTime? InstallDate { get; set; }
[Display(Name = "Group")]
[Required(ErrorMessage = "Please select a Group.")]
public int GroupId { get; set; }
public IEnumerable<SelectListItem> GroupItems { get; private set; }
public TheViewModel()
{
SiteId = -1;
SetSiteItems();
GroupId = -1;
SetGroupItems();
}
Here's code for the controller:
[HttpPost]
public ActionResult Submit(TheViewModel model)
{
DateTime DateEntered = DateTime.Now;
AssetModel AnAsset = new AssetModel();
AnAsset.AssetName = model.AssetName;
AnAsset.AssetNumber = model.AssetNumber;
AnAsset.AssetTypeId = model.AssetTypeId;
AnAsset.GroupId = model.GroupId;
AnAsset.ZoneId = model.ZoneId;
AnAsset.Description = model.Description;
//Note: Conversion from nullable to non-nullable type is dealt with.
if (model.InstallDate.HasValue)
{
AnAsset.InstallDate = model.InstallDate.Value;
}
//Send asset to insert method.
new AssetRepositoryModel().Insert(AnAsset);
return View();
}
Appreciate any help you can give me. Thanks.
probably solved using binding in Global.asax and defining your TheViewModelBinder class inherited from IModelBinder?
ModelBinders.Binders.Add( typeof(TheViewModel), new TheViewModelBinder() );
and binder class is something like this:
public class TheViewModelBinder : IModelBinder {
public object BindModel( ControllerContext controllerContext, ModelBindingContext bindingContext ) {
var theViewModel = new TheViewModel();
theViewModel.SiteId = int.Parse(request.Form.Get( "SiteId" ));
//other your code here
}
}