I have implemented Required validation for my MVC view. The text controls show the validation message but the kendo combobox doesnt. I'm doing an ajax postback.
Any reason why the comboxbox doest show the message? The work Type combo is mandatory, but its not showing the validation message.
View
#using (Ajax.BeginForm("ActivityWorkLog_Create", "Activity", new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "OnWorklogStatusSuccess",
OnFailure = "OnWorklogStatusFailure"
}, new { id = "workLogForm" }))
{
<div class="k-popup-edit-form k-window-content k-content" data-role="window">
<div class="k-edit-form-container">
#Html.HiddenFor(x => x.RequestID, new { data_bind = "value: requestId" })
#Html.HiddenFor(x => x.ActivityID, new { data_bind = "value: activityId" })
#Html.HiddenFor(x => x.CountryCode, new { data_bind = "value: countryCode" })
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.WorkLogAppliesToName)
</div>
<div class="editor-field">
#(Html.Kendo().ComboBoxFor(model => model.WorkLogAppliesToName)
.Name("WorkLogAppliesToID")
.Filter("contains")
.HtmlAttributes(new { style = "width:300px", #readonly = "readonly" })
.Placeholder("Select...")
.DataTextField("WorkLogAppliesToName")
.DataValueField("WorkLogAppliesToID")
.DataSource(dataSource => dataSource
.Read(read => read.Action("GetWorkLogAppliesTo", "WorkLog", new { id = 0 }).Type(HttpVerbs.Post)
)
)
)
#Html.ValidationMessageFor(model => model.WorkLogAppliesToName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.ActivitySLA)
</div>
<div class="editor-field">
#*#Html.EditorFor(model => model.ActivitySLA)*#
#Html.TextBoxFor(model => model.ActivitySLA, new { id = "ActivityDesc", #readonly = "readonly", Class = "textBoxFor" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.ActivityID)
</div>
<div class="editor-field">
#(Html.Kendo().ComboBoxFor(model => model.ActivityID)
.Name("Activity")
.Filter("contains")
.HtmlAttributes(new { style = "width:300px", #readonly = "readonly" })
.Placeholder("Select...")
.DataTextField("Description")
.DataValueField("ActivityID")
.DataSource(dataSource => dataSource
.Read(read => read.Action("GetActivity", "WorkLog").Data("additionalActivityInfo").Type(HttpVerbs.Post)
)//.ServerFiltering(true)
)//.CascadeFrom("ServiceID").Filter("contains")
)
#Html.ValidationMessageFor(model => model.ServiceID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.WorkLogType)
</div>
<div class="editor-field">
#(Html.Kendo().ComboBoxFor(model => model.WorkLogTypeCode)
.Name("WorkLogTypeCode1")
.Filter("contains")
.HtmlAttributes(new { style = "width:300px"})
.Placeholder("Select...")
.DataTextField("WorkLogType")
.DataValueField("WorkLogTypeCode")
.DataSource(dataSource => dataSource
.Read(read => read.Action("GetWorkLogType", "WorkLog").Data("additionalWLTInfo").Type(HttpVerbs.Post))
)
)
#Html.ValidationMessageFor(model => model.WorkLogTypeCode, "Please select a worklog type", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.WorkLogSubject)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.WorkLogSubject)
#Html.ValidationMessageFor(model => model.WorkLogSubject, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.WorkLogDetails)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.WorkLogDetails, new { htmlAttributes = new { #class = "form-control", cols = "50" } })
#Html.ValidationMessageFor(model => model.WorkLogDetails, "", new { #class = "text-danger" })
</div>
</div>
<div class="worklogStatusButtonAlign">
<button id="btnWorkLogSave" type="submit" class="k-button k-button-icontext k-primary k-grid-update">Save</button>
<button id="btnClose" type="button" class="k-button k-button-icontext k-grid-cancel">Cancel</button>
</div>
<div id="worklogStatusMessage"> </div>
</div>
</div>
}
Javacript
<script>
$(document).ready(function () {
var form = $("#workLogForm")
.removeData("validator")
.removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse(form);
});
View model
public class ActivityWorkLogViewModel
{
[ScaffoldColumn(false)]
[Display(Name = "WorkLogID", ResourceType = typeof(Resources.Resource))]
public int WorkLogID { get; set; }
[Required(ErrorMessage = "WorkLogType is required")]
[Display(Name = "WorkLogTypeCode", ResourceType = typeof(Resources.Resource))]
public string WorkLogTypeCode { get; set; }
[Display(Name = "WorkLogType", ResourceType = typeof(Resources.Resource))]
public string WorkLogType { get; set; }
[Required]
[Display(Name = "WorkLogAppliesToID", ResourceType = typeof(Resources.Resource))]
public int WorkLogAppliesToID { get; set; }
[Display(Name = "WorkLogAppliesToName", ResourceType = typeof(Resources.Resource))]
public string WorkLogAppliesToName { get; set; }
[Required]
[Display(Name = "RequestID", ResourceType = typeof(Resources.Resource))]
public int RequestID { get; set; }
[Display(Name = "ServiceID", ResourceType = typeof(Resources.Resource))]
public Nullable<int> ServiceID { get; set; }
[Display(Name = "ActivityID", ResourceType = typeof(Resources.Resource))]
public Nullable<int> ActivityID { get; set; }
[Required(ErrorMessage = "Subject is required")]
[Display(Name = "WorkLogSubject", ResourceType = typeof(Resources.Resource))]
public string WorkLogSubject { get; set; }
[Required(ErrorMessage = "Details is required")]
[Display(Name = "WorkLogDetails", ResourceType = typeof(Resources.Resource))]
public string WorkLogDetails { get; set; }
[Display(Name = "EmailTo", ResourceType = typeof(Resources.Resource))]
public string EmailTo { get; set; }
[Display(Name = "IsActive", ResourceType = typeof(Resources.Resource))]
public bool IsActive { get; set; }
[Display(Name = "CountryCode", ResourceType = typeof(Resources.Resource))]
public string CountryCode { get; set; }
[Display(Name = "ActivitySLA", ResourceType = typeof(Resources.Resource))]
public string ActivitySLA { get; set; }
}
Try to add this:
<script>
$(function () {
$("form").kendoValidator();
});
</script>
and/or:
<script>
$.validator.setDefaults({
ignore: ""
});
</script>
You can set validation rules to force the a item selection:
$("form").kendoValidator({
rules: {
invalidSelection: function (input) {
if (input.is("[name=COMBO_NAME]")) {
if (input.val() != "" && $("#TCOMBO_NAME").data("kendoComboBox").selectedIndex == -1) {
return false;
}
}
return true;
}
}
});
This way it travel all the fields of the form, being able to establish rules for each field. Regards.
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 have a partial view that returns a list of users address's, I need the user to be able to select one, then when they press "submit" along with the other details it takes the details from the selected address returns it to the controller, from there I know how to assign it where I want. How would I do this? Examples and help appreciated
Here is my controller for creating the order, view beneath;
[HttpPost]
public ActionResult AddressAndPayment(FormCollection values, string id)
{
var order = new Order();
TryUpdateModel(order);
//sets date and username
order.Username = User.Identity.Name;
order.OrderDate = DateTime.Now;
//Order gets saved
storeDB.Orders.Add(order);
storeDB.SaveChanges();
//Order gets processed
var cart = ShoppingCart.GetCart(this.HttpContext);
cart.CreateOrder(order);
//Save again, total not saving properly until now
storeDB.SaveChanges();
return RedirectToAction("Complete",
new { id = order.OrderId });
}
VIEW
#model T_shirt_Company_v3.Models.Order
#{
ViewBag.Title = "Address And Payment";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.HiddenFor(x => x.OrderId)
#Html.HiddenFor(x => x.OrderDate)
#Html.HiddenFor(x => x.PaymentTransactionId)
#Html.HiddenFor(x => x.Total)
#Html.HiddenFor(x => x.Username)
<div class="form-horizontal">
<h2>Address And Payment</h2>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#{Html.RenderAction("Listofaddresses", "Checkout");}
<h2>Select Postage type</h2>
#Html.EnumDropDownListFor(model => model.PostageList, "-- Please select postage type --")
<h2>Payment</h2>
<div class="form-group">
#Html.LabelFor(model => model.cardDetails.FullName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.cardDetails.FullName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.FullName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.cardDetails.CardNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.cardDetails.CardNo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.CardNo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.cardDetails.CardExpireMonth, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="row">
<div class="col-md-1">
#Html.EditorFor(model => model.cardDetails.CardExpireMonth, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.CardExpireMonth, "", new { #class = "text-danger" })
</div>
<div class="col-md-1">
#Html.EditorFor(model => model.cardDetails.CardExpireYear, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.CardExpireYear, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.cardDetails.Cvc, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.cardDetails.Cvc, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.cardDetails.Cvc, "", 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>
}
Partial View
#model IEnumerable<T_shirt_Company_v3.Models.deliveryAddress>
#foreach (var item in Model)
{
<div style="width: 180px">
<div class="thumbnail">
<p>#Html.DisplayFor(modelItem => item.FirstName) #Html.DisplayFor(modelItem => item.LastName) </p>
<p>#Html.DisplayFor(modelItem => item.Address)</p>
<p>#Html.DisplayFor(modelItem => item.City)</p>
<p>#Html.DisplayFor(modelItem => item.PostalCode)</p>
<p>#Html.DisplayFor(modelItem => item.Country)</p>
</div>
</div>
}
Address Class
public class deliveryAddress
{
[Key]
[ScaffoldColumn(false)]
public int AdressId { get; set; }
[ScaffoldColumn(false)]
public string UsersAddress { get; set; }
[Required]
[StringLength(16, ErrorMessage = "Your name is too long")]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Your last name is required.")]
[StringLength(16, ErrorMessage = "Last name is too long.")]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required(ErrorMessage = "Address is required.")]
public string Address { get; set; }
[Required(ErrorMessage = "City is required.")]
public string City { get; set; }
[Required(ErrorMessage = "Postcode is required.")]
[Display(Name = "Post Code")]
public string PostalCode { get; set; }
[Required(ErrorMessage = "Country is required.")]
public string Country { get; set; }
[Required(ErrorMessage = "Phone home number is required.")]
[Display(Name = "Home Telephone")]
public string Phone { get; set; }
[Required(ErrorMessage = "Phone mobile number is required.")]
[Display(Name = "Mobile")]
public string Mobile { get; set; }
}
}
I am unable to determine why my Razor View Page is not able to show Model Errors. I have applied Data Annotation to my model class. I am submitting the form using Ajax Form Upload Plugin (See Reference -> http://malsup.com/jquery/form/).
Model Class
public class Category
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
[FileExtensions(Extensions = ".jpeg,.jpg,.png",ErrorMessage ="Please upload valid image format.")]
public string BannerImage { get; set; }
[FileExtensions(Extensions = ".jpeg,.jpg,.png", ErrorMessage = "Please upload valid image format.")]
public string ThumbImage { get; set; }
private HttpPostedFileBase _bannerImageFile;
[Display(Name = "Banner Image")]
public HttpPostedFileBase BannerImageFile
{
get
{
return _bannerImageFile;
}
set
{
_bannerImageFile = value;
if(value != null)
BannerImage = _bannerImageFile.FileName;
}
}
private HttpPostedFileBase _thumbImageFile;
[Display(Name = "Thumb Image")]
public HttpPostedFileBase ThumbImageFile
{
get
{
return _thumbImageFile;
}
set
{
_thumbImageFile = value;
if (value != null)
ThumbImage = _thumbImageFile.FileName;
}
}
[Display(Name = "Meta Keywwords")]
public string MetaKeywords { get; set; }
[Display(Name = "Meta Description")]
public string MetaDescription { get; set; }
[Display(Name = "Created Date")]
public string CreatedDate { get; set; }
[Display(Name = "Last Updated Date")]
public string LastUpdatedDate { get; set; }
public bool Status { get; set; }
public List<SubCategory> SubCategories { get; set; }
public bool IsSaved(string spNameOrSql, Dictionary<string, object> parameters, QueryType type = QueryType.SQL)
{
try
{
if (type == QueryType.StoredProcedure)
{
var p = new SqlParameter[parameters.Count];
var count = 0;
foreach (var item in parameters)
{
var key = item.Key;
var value = item.Value;
value = String.Join(" ", Convert.ToString(value).Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries));
p[count++] = new SqlParameter("#" + key, value);
}
return Convert.ToBoolean(DataFunctions.ExecuteScalar(spNameOrSql, p, type));
}
return Convert.ToBoolean(DataFunctions.ExecuteScalar(spNameOrSql, type));
}
catch (Exception ex)
{
Error.Log(GetType().Name, MethodBase.GetCurrentMethod().ToString(), ex.Message, ex.Source, ex.StackTrace);
return false;
}
}
}
Controller
public ActionResult AddCategory(Category model)
{
if (ModelState.IsValid)
{
var param = model.GetType().GetProperties().ToDictionary(prop => prop.Name,
prop => prop.GetValue(model, null));
param.Remove(Nameof<Category>.Property(e => e.Id));
param.Remove(Nameof<Category>.Property(e => e.BannerImageFile));
param.Remove(Nameof<Category>.Property(e => e.ThumbImageFile));
param.Remove(Nameof<Category>.Property(e => e.CreatedDate));
param.Remove(Nameof<Category>.Property(e => e.LastUpdatedDate));
var result = model.IsSaved(AppConstants.StoredProcedures.CATEGORY_ADD, param, QueryType.StoredProcedure);
if (result)
{
for (int i = 0; i < Request.Files.Count; i++)
{
switch (Request.Files.Keys[i])
{
case "BannerImageFile":
UploadImage(Request.Files[i], AppConstants.FilePath.CATEGORY_BANNER_IMAGE_PATH);
break;
case "ThumbImageFile":
UploadImage(Request.Files[i], AppConstants.FilePath.CATEGORY_THUMB_IMAGE_PATH);
break;
}
}
ModelState.Clear();
}
}
return PartialView("_PartialAddCategory",model);
}
View
#model TristarJewelry.Shared.Models.Category
<script type="text/javascript">
$(document).ready(function () {
var options = {
beforeSubmit: BeginLoader,
success: OnSuccess,
error: OnFailure,
target: '#myForm'
};
$('#myForm').ajaxForm(options);
});
function OnSuccess() {
$("#app_message").removeClass("alert-success alert-danger alert-warning alert-info");
$("#app_message").addClass("alert-success");
$("#app_message").html("Category Succesfully Added !");
$("#app_message").fadeIn(2000).delay(2000).fadeOut(2000);
StopLoader();
}
function OnFailure() {
$("#app_message").html("Oops something went wrong ! Try after sometime. ");
$("#app_message").removeClass("alert-success alert-danger alert-warning alert-info");
$("#app_message").addClass("alert-danger");
$("#app_message").fadeIn(2000).delay(3000).fadeOut(2000);
}
function BeginLoader() {
$('#loader').modal({ toggle: "model", backdrop: 'static', keyboard: false });
}
function StopLoader() {
$('#loader').modal("hide");
}
</script>
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Add Category</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">
Please fill all the details.
</div>
<div class="panel-body">
<div class="row">
<form id="myForm" action="#Url.Action("AddCategory","Dashboard")" method="POST" enctype = "multipart/form-data">
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-lg-6">
<div class="form-group">
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control", #placeholder = "Enter Name" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description)
#Html.TextAreaFor(model => model.Description, new { #class = "form-control", #placeholder = "Enter Description", #rows = "3", style = "resize:vertical" })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.ThumbImageFile)
#Html.TextBoxFor(model => model.ThumbImageFile, new { type = "file" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.BannerImageFile)
#Html.TextBoxFor(model => model.BannerImageFile, new { type = "file" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.Status)
#Html.CheckBoxFor(model => model.Status)
#Html.ValidationMessageFor(model => model.Status, "", new { #class = "text-danger" })
</div>
<button type="submit" class="btn btn-default">Submit Button</button>
<button id="form_reset" type="reset" class="btn btn-default">Reset Button</button>
</div>
<!-- /.col-lg-6 (nested) -->
<div class="col-lg-6">
<div class="form-group">
#Html.LabelFor(model => model.MetaKeywords)
#Html.EditorFor(model => model.MetaKeywords, new { htmlAttributes = new { #class = "form-control", #placeholder = "Enter Meta Keywords" } })
#Html.ValidationMessageFor(model => model.MetaKeywords, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.MetaDescription)
#Html.TextAreaFor(model => model.MetaDescription, new { #class = "form-control", #placeholder = "Enter Meta Description", #rows = "3", style = "resize:vertical" })
#Html.ValidationMessageFor(model => model.MetaDescription, "", new { #class = "text-danger" })
</div>
</div>
<!-- /.col-lg-6 (nested) -->
</form>
</div>
<!-- /.row (nested) -->
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
</div>
On Controller ,ModelState.IsValid becomes false if any of the model property doesn't validate but it is not displaying error on view page. Don't know why. can anybody tell me.
Note* : I am not using Ajax.BeginForm here because i can't able to upload files with this approach. So instead i am using jquery form upload puglin.
Any help would be appriciated. If you need to know anything let me know here.
I'm in VS 2013 and am completely new to ASP.NET MVC in general. I have been attempting to do this for sometime with no luck. Have a user complete a form with an image upload, and have that form with the image written to the DB. I know its best to write the path to the DB and store the image in the content folder of the application but I have no idea how to do any of this. Can someone give me a starting point?
I also have a ClientUtility.cs that is used to populate drop-downs but I don't see this being needed right now.
Currently the data type for the image ref in the db is VARCHAR(255).
Controller:
private TpsEntities db = new TpsEntities();
[HttpPost]
public ActionResult SaveStaffDetails(RegisterStaffViewModel model)
{
var staff = new staffTable()
{
staffFirstName = model.FirstName,
staffLastName = model.LastName,
staffTitle = model.SelectedTitle,
staffAddress = model.Address,
staffCity = model.City,
staffState = model.SelectedState,
staffZip = model.ZipCode,
staffExperience = model.SelectedExperience,
staffEducation = model.SelectedEducation,
desiredSalary = model.SelectedSalary,
staffProfession = model.SelectedProfession,
staffAvailibity = model.SelectedAvailability,
staffEmail = model.EmailAddress,
staffPhoneNum = model.PhoneNumber,
staffPhoto = null,
userID = model.UserId
};
using (var db = new TpsEntities())
{
db.staffTables.Add(staff);
db.SaveChanges();
}
var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = userManager.FindById(model.UserId);
userManager.AddToRole(model.UserId, "Staff");
ClaimsIdentity identity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
identity.AddClaim(new Claim(ClaimTypes.Role, "Staff"));
var AuthenticationManager = System.Web.HttpContext.Current.GetOwinContext().Authentication;
AuthenticationManager.SignIn(new AuthenticationProperties() {IsPersistent = false}, identity);
return RedirectToAction("Index", "Home");
}
}
ViewModel:
public class RegisterStaffViewModel
{
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[Display(Name = "Address")]
public string Address { get; set; }
public System.Web.UI.WebControls.ListItemCollection Title { get; set; }
[Required]
[Display(Name = "Title")]
public string SelectedTitle { get; set; }
[Required]
[Display(Name = "City")]
public string City { get; set; }
public System.Web.UI.WebControls.ListItemCollection States { get; set; }
[Required]
[Display(Name = "State")]
public string SelectedState { get; set; }
[Required]
[Display(Name = "Zip Code")]
public double? ZipCode { get; set; }
[Required]
[Phone]
[Display(Name = "Phone Number")]
public string PhoneNumber { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email Address")]
public string EmailAddress { get; set; }
public System.Web.UI.WebControls.ListItemCollection Experience { get; set; }
[Required]
[Display(Name = "Experience")]
public string SelectedExperience { get; set; }
public System.Web.UI.WebControls.ListItemCollection Education { get; set; }
[Required]
[Display(Name = "Education")]
public string SelectedEducation { get; set; }
public System.Web.UI.WebControls.ListItemCollection Salary { get; set; }
[Required]
[Display(Name = "Salary")]
public string SelectedSalary { get; set; }
public System.Web.UI.WebControls.ListItemCollection Profession { get; set; }
[Required]
[Display(Name = "Profession")]
public string SelectedProfession { get; set; }
public System.Web.UI.WebControls.ListItemCollection Availability { get; set; }
[Required]
[Display(Name = "Availability")]
public string SelectedAvailability { get; set; }
public string UserId { get; set; }
}
View:
#*Start of Registration Form for Staff*#
#using (Html.BeginForm("SaveStaffDetails", "Staff", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.UserId)
<fieldset>
<!-- Form Name -->
<legend>Register New Staff</legend>
#*First Name*#
<div class="form-group">
<div class="col-md-6">
#Html.TextBoxFor(m => m.FirstName, new { #class = "form-control input-md", #placeholder = "First Name" })
</div>
</div>
#*Last Name*#
<div class="form-group">
<div class="col-md-6">
#Html.TextBoxFor(m => m.LastName, new { #class = "form-control input-md", #placeholder = "Last Name" })
</div>
</div>
#*Person Title*#
<div class="form-group">
<label class="col-md-6 control-label" for="title">Title</label>
<div class="col-md-6">
#Html.DropDownListFor(m => m.SelectedTitle, new SelectList(Model.Title, "Text", "Value"))
</div>
</div>
#*Address Line*#
<div class="form-group">
<div class="col-md-6">
#Html.TextBoxFor(m => m.Address, new { #class = "form-control input-md", #placeholder = "Address" })
</div>
</div>
#*City*#
<div class="form-group">
<div class="col-md-6">
#Html.TextBoxFor(m => m.City, new { #class = "form-control input-md", #placeholder = "City" })
</div>
</div>
#*State*#
<div class="form-group">
<label class="col-md-6 control-label" for="state">State</label>
<div class="col-md-6">
#Html.DropDownListFor(m => m.SelectedState, new SelectList(Model.States, "Text", "Value"))
</div>
</div>
#*Zip Code*#
<div class="form-group">
<div class="col-md-6">
#Html.TextBoxFor(m => m.ZipCode, new { #class = "form-control input-md", #placeholder = "Zip Code" })
</div>
</div>
#*Phone Number*#
<div class="form-group">
<div class="col-md-6">
#Html.TextBoxFor(m => m.PhoneNumber, new { #class = "form-control input-md", #placeholder = "Phone Number" })
</div>
</div>
#*Email Address*#
<div class="form-group">
<div class="col-md-6">
#Html.TextBoxFor(m => m.EmailAddress, new { #class = "form-control input-md", #placeholder = "Email Address" })
</div>
</div>
#*Experience*#
<div class="form-group">
<label class="col-md-6 control-label" for="experience">Experience</label>
<div class="col-md-6">
#Html.DropDownListFor(m => m.SelectedExperience, new SelectList(Model.Experience, "Text", "Value"))
</div>
</div>
#*Education*#
<div class="form-group">
<label class="col-md-6 control-label" for="education">Education</label>
<div class="col-md-6">
#Html.DropDownListFor(m => m.SelectedEducation, new SelectList(Model.Education, "Text", "Value"))
</div>
</div>
#*Desired Salary*#
<div class="form-group">
<label class="col-md-6 control-label" for="salary">Desired Salary</label>
<div class="col-md-6">
#Html.DropDownListFor(m => m.SelectedSalary, new SelectList(Model.Salary, "Text", "Value"))
</div>
</div>
#*Profession*#
<div class="form-group">
<label class="col-md-6 control-label" for="profession">Profession</label>
<div class="col-md-6">
#Html.DropDownListFor(m => m.SelectedProfession, new SelectList(Model.Profession, "Text", "Value"))
</div>
</div>
#*Availability*#
<div class="form-group">
<label class="col-md-6 control-label" for="availability">Availability</label>
<div class="col-md-6">
#Html.DropDownListFor(m => m.SelectedAvailability, new SelectList(Model.Availability, "Text", "Value"))
</div>
</div>
<!-- INSERT IMAGE UPLOAD HERE -->
</fieldset>
<input type="submit" value="Save" />
}
Edit your controller as the following code.I assumed that staffPhoto is taking picturepath.
public ActionResult SaveStaffDetails(RegisterStaffViewModel model,HttpPostedFileBase image)
{
if (Request.Files.Count > 0) {
string FileName = Guid.NewGuid().ToString().Replace("-", "");
string Path = System.IO.Path.GetExtension(Request.Files[0].FileName);
string FullPath = "~/Images/StaffPhotos/" + FileName + Path;
Request.Files[0].SaveAs(Server.MapPath(FullPath));
staffPhoto = FileName + Path;
}
}
In your view you need a file post input
<input type="file" class="filestyle" name="image" data-classbutton="btn btn-primary" data-input="false">
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
}
}