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
}
}
Related
I've tryed to merge my create and edit actions into a save action, but for some reason, when I try to insert a new Cliente, the modelState trys to validate de ID colum. If I comment out the hidden field ID in the view, it works.
Would you give me a clue, please!?
View
#model WebApplicationCursoASPNET_V3.ViewModels.FormularioClienteViewModel
#{
ViewBag.Title = "Novo";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2> Cliente</h2>
#using (#Html.BeginForm("Gravar", "Cliente"))
{
<div class="form-group">
#Html.LabelFor(m => m.cliente.Nome)
#Html.TextBoxFor(m => m.cliente.Nome, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.cliente.Nome, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.cliente.TipoAssinaturaId)
#Html.DropDownListFor(m => m.cliente.TipoAssinaturaId, new SelectList(Model.tiposAssinatura, "Id", "Nome"), "<< Selecione a assinatura >>", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.cliente.TipoAssinaturaId, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.cliente.Aniversario)
#Html.TextBoxFor(m => m.cliente.Aniversario, "{0:d}", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.cliente.Aniversario)
</div>
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.cliente.EstaInscritoEmAssinaturas) Está inscrito em assinaturas
</label>
</div>
#Html.HiddenFor(m => m.cliente.Id)
#Html.ValidationMessageFor(m => m.cliente.Id, "", new {#class="text-danger"})
<br>
<button type="submit" class="btn btn-primary">Gravar</button>
}
Controller
[HttpPost]
public ActionResult Gravar(FormularioClienteViewModel dadosFormulario)
{
if (dadosFormulario.cliente.Id == 0)
{
if (ModelState.IsValid)
{
_context.Clientes.Add(dadosFormulario.cliente);
_context.SaveChanges();
return RedirectToAction("Index", "Cliente");
}
var vwModel = new FormularioClienteViewModel
{
cliente = dadosFormulario.cliente,
tiposAssinatura = _context.TipoAssinaturas.OrderBy(m => m.Nome).ToList()
};
return View("Form", vwModel);
}
var clienteDB = _context.Clientes.SingleOrDefault(c => c.Id == dadosFormulario.cliente.Id);
if (clienteDB == null)
{
return HttpNotFound();
}
clienteDB.Nome = dadosFormulario.cliente.Nome;
clienteDB.TipoAssinaturaId = dadosFormulario.cliente.TipoAssinaturaId;
clienteDB.Aniversario = dadosFormulario.cliente.Aniversario;
clienteDB.EstaInscritoEmAssinaturas = dadosFormulario.cliente.EstaInscritoEmAssinaturas;
_context.SaveChanges();
return RedirectToAction("Index", "Cliente");
}
Model
public class Cliente
{
public int Id { get; set; }
[Display(Name = "Nome do cliente")]
[Required]
[StringLength(255,ErrorMessage = "Tamanho máximo de 255 caracteres")]
public string Nome { get; set; }
[Display(Name = "Está inscrito em assinaturas")]
public bool EstaInscritoEmAssinaturas { get; set; }
public TipoAssinatura TipoAssinatura { get; set; }
[Display(Name = "Tipo de assinatura")]
public int TipoAssinaturaId { get; set; }
public DateTime? Aniversario { get; set; }
}
Error msg: O campo Id é obrigatório. / Field Id is required
Ideally, it is recommended to use different calls for save and update with different DTO.
In your case, now you need to make Id nullable and validate it with custom logic in Update.
public int? Id { get; set; }
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'm trying to send an email everytime the user creates a new comment.
I've already installed the package Postal.MVC5
Comment Model
public int Id { get; set; }
[Required]
[MinLength(3)]
[MaxLength(20)]
public string Asunto { get; set; }
[Required]
public string Detalle { get; set; }
[DataType(DataType.Date)]
public DateTime Fecha { get; set; }
[DataType(DataType.Time)]
public DateTime Hora { get; set; }
public virtual Local local { get; set; }
public virtual string username { get; set; }
NewCommentEmail Model
public class NewCommentEmail : Email
{
public string To { get; set; }
public string UserName { get; set; }
public string Comment { get; set; }
}
Controller
[HttpPost]
public ActionResult AgregarComentario(NotasAdjuntas nota)
{
try
{
var localId = int.Parse(Request["LocalID"]);
nota.username = Session["Username"].ToString();
using (var db = new AutoContex())
{
nota.local = db.Locales.Find(localId);
db.Entry(nota.local).Reference(p => p.Proveedor).Load();
db.Notas.Add(nota);
db.SaveChanges();
}
var email = new NewCommentEmail();
email.To = "emilia.lasaga#pedidosya.com";
email.UserName = nota.username;
email.Comment = nota.Asunto;
email.Send();
return RedirectToAction("Details", new { #id = localId });
}
catch
{
return View();
}
}
I've also added this to the webconfig
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="C:\Temp\" />
</smtp>
</mailSettings>
The error I'm getting is:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:Couldn't make connection on time of execution in a NULL reference
The line that is getting the error is:
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Notas Adjuntas</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div>
<ledgend>Datos del Local<ledgend>
<div class="panel-title">Id</div>
<div class="text-left">
<input type="Text" name="LocalID" id="LocalID" value="#ViewBag.Local.Id" />
</div>
<table class="table">
<tr>
<th>Id</th>
<th>Viejo Id</th>
<th>Nombre</th>
<th>Unificado Con</th>
<th>Dirección</th>
<th>Telefono</th>
<th>Localidad</th>
<th>Provincia</th>
<th>Proveedor</th>
<th>Estado</th>
<th>Fecha Instalación</th>
</tr>
<tr>
<td>#ViewBag.Local.NuevoId</td>
<td>#ViewBag.Local.ViejoId</td>
<td>#ViewBag.Local.NombreComercio</td>
<td>#ViewBag.Local.UnificadoCon</td>
<td>#ViewBag.Local.Direccion</td>
<td>#ViewBag.Local.Telefono</td>
<td>#ViewBag.Local.Localidad</td>
<td>#ViewBag.Local.Provincia</td>
<td>#ViewBag.Local.Proveedor.Nombre</td>
<td>#ViewBag.Local.Estado.State</td>
<td>#ViewBag.Local.FechaInstalacion</td>
</tr>
</table>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Asunto, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Asunto, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Asunto, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Detalle, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Detalle, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Detalle, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Fecha, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Fecha, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Fecha, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Hora, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Hora, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Hora, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
I was able send the email through smtps
It wasn't the frist approach I was looking for (I wanted to do it through Postal.MVC5)
What I did was this:
New Class to create the email
using System.Net.Mail;
using System.Net;
namespace AutoPlanMCV.Models
{
public class NewCommentEmail
{
public static string GmailUsername { get; set; }
public static string GmailPassword { get; set; }
public static string GmailHost { get; set; }
public static int GmailPort { get; set; }
public static bool GmailSSL { get; set; }
public string ToEmail { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public bool IsHtml { get; set; }
static NewCommentEmail()
{
GmailHost = "smtp.gmail.com";
GmailPort = 25; // Gmail can use ports 25, 465 & 587; but must be 25 for medium trust environment.
GmailSSL = true;
}
public void Send()
{
SmtpClient smtp = new SmtpClient();
smtp.Host = GmailHost;
smtp.Port = GmailPort;
smtp.EnableSsl = GmailSSL;
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential(GmailUsername, GmailPassword);
using (var message = new MailMessage(GmailUsername, ToEmail))
{
message.Subject = Subject;
message.Body = Body;
message.IsBodyHtml = IsHtml;
smtp.Send(message);
}
}
}
Controller
public ActionResult AgregarComentario(NotasAdjuntas nota)
{
try
{
var localId = int.Parse(Request["LocalID"]);
nota.username = Session["Username"].ToString();
using (var db = new AutoContex())
{
nota.local = db.Locales.Find(localId);
db.Entry(nota.local).Reference(p => p.Proveedor).Load();
db.Notas.Add(nota);
db.SaveChanges();
if (nota.Asunto.Contains("capa"))
{
NewCommentEmail.GmailUsername = "youremail#gmail.com";
NewCommentEmail.GmailPassword = "yourpassword";
NewCommentEmail mailer = new NewCommentEmail();
mailer.ToEmail = "Emailto#gmail.com";
mailer.Subject = nota.Asunto;
mailer.Body = nota.local.NuevoId + " -- --" + nota.local.NombreComercio + "<br />" + nota.Detalle + "<br /> Hora:" + nota.Hora;
mailer.IsHtml = true;
mailer.Send();
}
}
return RedirectToAction("Details", new { #id = localId });
}
catch
{
return View();
}
}
I removed what I had in the webconfig, and I didn't edit my view.
I didn't receive any errors after that
I'm having trouble retrieving the correct value to my DropDownList Control within the Edit Action.
Customer Model:
public class Customer
{
public int CustId { get; set; }
public string CustDisplayName { get; set; }
public string CustFirstName { get; set; }
public string CustLastName { get; set; }
public string CustCompanyName { get; set; }
public string CustAddress { get; set; }
public string CustPhoneNumber { get; set; }
public string CustMobileNumber { get; set; }
public string CustEmailAddress { get; set; }
public int StId { get; set; }
public State State { get; set; }
}
State Model:
public class State
{
public int StId { get; set; }
public string StAbbr { get; set; }
public List<Customer> Customers { get; set; }
}
Manufacturer Model:
public class Manufacturer
{
public int MfrId { get; set; }
public string MfrCompanyName { get; set; }
public string MfrWebsiteDomainName { get; set; }
}
CustomerFormViewModel
public class CustomerFormViewModel
{
public int CustId { get; set; }
[Required(ErrorMessage = "Display Name is required!")]
[Display(Name = "Display Name")]
[StringLength(100)]
public string CustDisplayName { get; set; }
[Display(Name = "First Name")]
[StringLength(50)]
public string CustFirstName { get; set; }
[Display(Name = "Last Name")]
[StringLength(50)]
public string CustLastName { get; set; }
[Display(Name = "Company Name")]
[StringLength(50)]
public string CustCompanyName { get; set; }
[Display(Name = "Phone Number")]
[DataType(DataType.PhoneNumber)]
[StringLength(12)]
[RegularExpression(#"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}", ErrorMessage = "Invalid Phone Number format!")]
public string CustPhoneNumber { get; set; }
[Display(Name = "Mobile Number")]
[DataType(DataType.PhoneNumber)]
[StringLength(12)]
[RegularExpression(#"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}", ErrorMessage = "Invalid Number!")]
public string CustMobileNumber { get; set; }
[Display(Name = "Email Address")]
[DataType(DataType.EmailAddress)]
[StringLength(320)]
public string CustEmailAddress { get; set; }
[Required(ErrorMessage = "Address is required!")]
[Display(Name = "Address")]
[StringLength(100)]
public string CustAddress { get; set; }
[Required(ErrorMessage = "State is required!")]
[Display(Name = "State")]
public int StId { get; set; }
public IEnumerable<State> States { get; set; }
}
CustomerController:
public class CustomerController : Controller
{
private WebAppDbContext _context;
public CustomerController(WebAppDbContext context)
{
_context = context;
}
// GET: /<Customer>/
public IActionResult Index()
{
return View(_context.Customers.ToList());
}
public ActionResult Create()
{
var states = _context.States.ToList();
var viewModel = new CustomerFormViewModel
{
States = states
};
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerFormViewModel vm)
{
if (ModelState.IsValid)
{
var customer = new Customer();
{
customer.CustDisplayName = vm.CustDisplayName;
customer.CustFirstName = vm.CustFirstName;
customer.CustLastName = vm.CustLastName;
customer.CustCompanyName = vm.CustCompanyName;
customer.CustAddress = vm.CustAddress;
customer.CustPhoneNumber = vm.CustPhoneNumber;
customer.CustMobileNumber = vm.CustMobileNumber;
customer.CustEmailAddress = vm.CustEmailAddress;
customer.StId = vm.StId;
}
_context.Customers.Add(customer);
_context.SaveChanges();
return RedirectToAction("Index");
}
else
{
vm.States = _context.States.ToList();
return View(vm);
}
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var customervm = new CustomerFormViewModel();
{
Customer customer = _context.Customers.SingleOrDefault(c => c.CustId == id);
if (customer == null)
{
return NotFound();
}
customervm.CustId = customer.CustId;
customervm.CustDisplayName = customer.CustDisplayName;
customervm.CustFirstName = customer.CustFirstName;
customervm.CustLastName = customer.CustLastName;
customervm.CustCompanyName = customer.CustCompanyName;
customervm.CustAddress = customer.CustAddress;
customervm.CustPhoneNumber = customer.CustPhoneNumber;
customervm.CustMobileNumber = customer.CustMobileNumber;
customervm.CustEmailAddress = customer.CustEmailAddress;
customervm.StId = customer.StId;
}
return View(customervm);
}
}
Create View:
<div class="form-group">
#Html.LabelFor(c => c.CustDisplayName)
#Html.TextBoxFor(c => c.CustDisplayName, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustDisplayName)
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustFirstName)
#Html.TextBoxFor(c => c.CustFirstName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustLastName)
#Html.TextBoxFor(c => c.CustLastName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustCompanyName)
#Html.TextBoxFor(c => c.CustCompanyName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustAddress)
#Html.TextBoxFor(c => c.CustAddress, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustAddress)
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustPhoneNumber)
#Html.TextBoxFor(c => c.CustPhoneNumber, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustPhoneNumber)
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustMobileNumber)
#Html.TextBoxFor(c => c.CustMobileNumber, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustMobileNumber)
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustEmailAddress)
#Html.TextBoxFor(c => c.CustEmailAddress, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustEmailAddress)
</div>
<div class="form-group">
#Html.LabelFor(s => s.StId)
#Html.DropDownListFor(s => s.StId, new SelectList(Model.States, "StId", "StAbbr"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(s => s.StId)
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
Edit View:
<div class="form-group">
#Html.LabelFor(c => c.CustDisplayName)
#Html.TextBoxFor(c => c.CustDisplayName, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustDisplayName)
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustFirstName)
#Html.TextBoxFor(c => c.CustFirstName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustLastName)
#Html.TextBoxFor(c => c.CustLastName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustCompanyName)
#Html.TextBoxFor(c => c.CustCompanyName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustAddress)
#Html.TextBoxFor(c => c.CustAddress, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustAddress)
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustPhoneNumber)
#Html.TextBoxFor(c => c.CustPhoneNumber, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustPhoneNumber)
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustMobileNumber)
#Html.TextBoxFor(c => c.CustMobileNumber, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustMobileNumber)
</div>
<div class="form-group">
#Html.LabelFor(c => c.CustEmailAddress)
#Html.TextBoxFor(c => c.CustEmailAddress, new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.CustEmailAddress)
</div>
<div class="form-group">
#Html.LabelFor(s => s.StId)
#Html.DropDownListFor(s => s.StId, new SelectList(Model.States, "StId", "StAbbr"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(s => s.StId)
</div>
#Html.HiddenFor(c => c.CustId)
<div class="form-group">
<button type="submit" class="btn btn-primary">Update</button>
</div>
It is same as your create action, Load the collection property for all states (States) and also set the property for the selected item (StId) on your view model object.
So add this code to your Edit GET action method.
var customervm = new CustomerFormViewModel();
{
// Your existing code to map the entity property values goes here
}
//Load all the states
var states = _context.States.ToList();
customervm.States = states;
//Set the selected state
customervm.StId = customer.StId;
return View();
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"/>