I am having a hard time to show dropdownlist for in the view, the values will be populated from database. I am using MS SQL Server as the database.
I want to show a drop down list in ApplyingFor which will be populated from database.
Please help me out.
This is the Model
public class CandidateProfile
{
[Display(Name = "Candidate Name")]
[Required(ErrorMessage = "Provide a Name", AllowEmptyStrings=false)]
[DataType(DataType.Text)]
public string CandidateName { get; set; }
[Required(ErrorMessage = "Provide Your Address",AllowEmptyStrings = false)]
[Display(Name = "Address")]
[DataType(DataType.MultilineText)]
public string Address { get; set; }
[Display(Name = "Phone Number")]
[Required(ErrorMessage = "Provide a Phone Number")]
[RegularExpression("^([07][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 8[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 9[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])$", ErrorMessage = "Enter Valid Mobile Number")]
public string PhoneNumber { get; set; }
[Display (Name = "Email-Id")]
[Required(ErrorMessage="Provide an email-id")]
[EmailValidator]
public string EmailId { get; set; }
[Display (Name = "Applying For")]
public string **ApplyingFor** { get; set; }
[Display (Name = "Experience")]
[Required(ErrorMessage = "")]
public int Experience { get; set; }
[Display (Name = "Present Location")]
[Required(ErrorMessage = "")]
public string PresentLocation { get; set; }
}
public class ApplyingPositions
{
public IEnumerable<ApplyingPositions> ApplyingPosition { get; set; }
}
public class ApplyingPosition
{
public int APId { get; set; }
public string Designation { get; set; }
}
This is the View:
#model Recruitment.Models.CandidateProfile
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>CandidateProfile</legend>
<div class="editor-label">
#Html.LabelFor(model => model.CandidateName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CandidateName)
#Html.ValidationMessageFor(model => model.CandidateName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNumber)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumber)
#Html.ValidationMessageFor(model => model.PhoneNumber)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmailId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmailId)
#Html.ValidationMessageFor(model => model.EmailId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ApplyingFor)
<div class="editor-field">
#Html.EditorFor(model => model.ApplyingFor)
#Html.ValidationMessageFor(model => model.ApplyingFor)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Experience)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Experience)
#Html.ValidationMessageFor(model => model.Experience)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PresentLocation)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PresentLocation)
#Html.ValidationMessageFor(model => model.PresentLocation)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
You need to pass the List of Options from your controller to view. So, before returning View
var listOfPositions = new List<ApplyingPosition>();
listOfPositions = //Call the service to populate the listOfPositions from Database here
ViewBag.PositionsList = new SelectList(listOfPositions, "APId", "Designation");
In your view instead of #Html.EditorFor(model => model.ApplyingFor)
#Html.DropDownListFor(m => m.ApplyingFor, (SelectList)ViewBag.PositionsList, "Select")
populate lstApplyingFor (list) form your DB. and in your controller
ViewBag.ApplyingFor = new SelectList(lstApplyingFor, "Id", "Name");
and in view:-
#Html.DropDownList(m => m.ApplyingFor,"ApplyingFor", "--Select--")
First-
1) You need to create the source for dropdown as-
var listForApplyingFor= db.Table.Select(o=> new SelectListItem{
Value=o.ID,
Text= o.Text
}).ToList();
ViewBag.ItemsApplyingFor= listForApplyingFor
.Cshtml View-
#Html.DropdownListFor(m=>m.ApplyingFor, new SelectList(ViewBag.ItemsApplyingFor,"Value","Text"),"Select...", htmlAttributes:new{ })
Let me know if it helps.
Related
I'm trying to pass these textbox values to the controller:
#model DTOs.QuestionDTO
#{
ViewBag.Title = "AddQuestion";
}
<h2>AddQuestion</h2>
#using (Html.BeginForm("AddQuestionDB", "Exam"))
{
<fieldset>
<legend>Add Question</legend>
<div class="editor-label">
#Html.LabelFor(model => model.QuestionDes)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.QuestionDes , new { #id="question" , #name="question"})
#Html.ValidationMessageFor(model => model.QuestionDes)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Answer1)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Answer1 , new { #id="a1" , #name="a1"})
#Html.ValidationMessageFor(model => model.Answer1)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Answer2)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Answer2 , new { #id="a2" , #name="a2"})
#Html.ValidationMessageFor(model => model.Answer2)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Answer3)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Answer3 , new { #id="a3" , #name="a3"})
#Html.ValidationMessageFor(model => model.Answer3)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Answer4)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Answer4 , new { #id="a4" , #name="a4"})
#Html.ValidationMessageFor(model => model.Answer4)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Correct)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Correct , new { #id="correct" , #name="correct"})
#Html.ValidationMessageFor(model => model.Correct)
</div>
<p>
<input type="submit" value="Add" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to Login", "Login")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
this is how my controller method looks like:
public ActionResult AddQuestionDB(string question, string a1, string a2, string a3, string a4, string correct)
{
ViewBag.a1 = a1;
ViewBag.a2 = a2;
ViewBag.a3 = a3;
ViewBag.a4 = a4;
ViewBag.correct = correct;
return View();
}
And i have created a View to display this Viewbag variables... but these variables wont come up.
it seem to be that these variables are null..
#{
ViewBag.Title = "AddQuestionDB";
}
<h2>AddQuestionDB</h2>
<p>#Session["q"]</p>
<p>#ViewBag.question</p>
<p>#ViewBag.a1</p>
<p>#ViewBag.a2</p>
<p>#ViewBag.a3</p>
<p>#ViewBag.a4</p>
<p>#ViewBag.correct</p>
this is how my DTO looks like:
namespace DTOs
{
public class QuestionDTO
{
public int ID { get; set; }
public string QuestionDes { get; set; }
public string Answer1 { get; set; }
public string Answer2 { get; set; }
public string Answer3 { get; set; }
public string Answer4 { get; set; }
public int Correct { get; set; }
}
}
Can you please explain, how i should do this??
thank you!!!
Instead of -
public ActionResult AddQuestionDB(string question, string a1, string a2, string a3, string a4, string correct)
{
// Your custom code
return View();
}
have this code -
public ActionResult AddQuestionDB(QuestionDTO question)
{
// Use 'question' object here to get posted values.
return View();
}
I replicated your scenario in a small sample project on my local, here is the outcome when I debugged the code with breakpoint -
Html.EditorFor does not support setting attributes, which is why your original code wasn't working. The name attribute didn't match the parameter names in your controller action, so they were assigned null.
You can either use #ramiramilu's answer, or you could use TextBoxFor instead:
#Html.TextBoxFor(model => model.Correct , new { id="correct" , Name="correct"})
(Note that Name must be capitalized in order for this to work).
Example: https://dotnetfiddle.net/ZfzCaZ
I am trying to save picture in folder and store path in Sqlserver 2008 using entity framework. I need register the user with picture. My code is saving all the data in database except picture and picture path.
My model is
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class customer
{
[Display(Name="Username")]
public string user_id { get; set; }
[Display(Name = "Password")]
public string password { get; set; }
[Display(Name = "First Name")]
public string first_name { get; set; }
[Display(Name = "Last Name")]
public string last_name { get; set; }
[Display(Name = "Address")]
public string address { get; set; }
[Display(Name = "City")]
public string city { get; set; }
[Display(Name = "State")]
public string state { get; set; }
[Display(Name = "Zip")]
public Nullable<int> zip { get; set; }
[Display(Name = "Country")]
public string country { get; set; }
[Display(Name = "Email Address")]
public string email { get; set; }
[Display(Name = "Phone")]
public string phone { get; set; }
[Display(Name = "Picture")]
public string picture { get; set; }
[Display(Name = "Registration Date")]
public Nullable<System.DateTime> reg_date { get; set; }
[Display(Name = "Status")]
public string status { get; set; }
[Display(Name = "Keep me logged in")]
public bool rememberme { get; set; }
}
}
My Controller is
[HttpPost]
public ActionResult Register(customer customer, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (file != null)
{
file.SaveAs(HttpContext.Server.MapPath("~/image/") + file.FileName);
customer.picture = file.FileName;
}
onlinebookstoreEntities1 db = new onlinebookstoreEntities1();
db.customers.Add(customer);
db.SaveChanges();
return RedirectToAction("Index","Home");
}
return View(customer);
}
and my view is
#using (Html.BeginForm("Register", "Account", FormMethod.Post, new { enctype = "multipart/form-data" })) {
<div class="editor-label">
#Html.LabelFor(model => model.first_name)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.first_name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.last_name)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.last_name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.user_id)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.user_id)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.password)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.address)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.city)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.city)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.state)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.state)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.zip)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.zip)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.country)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.country)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.email)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.phone)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.phone)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.picture)
</div>
<div class="btnreg">
<input type="file" id="picture" value="Upload Picture" />
</div>
<div class="txtreg">
#Html.CheckBoxFor(model => model.rememberme) #Html.LabelFor(model => model.rememberme)
</div>
<input type="submit" value="Create Account" name="btnsub" />
}
If you want to save a picture in the database your property have to look like this:
[DisplayName("Billede")]
[MaxLength]
public byte[] PhotoFile { get; set; }
and not:
[Display(Name = "Picture")]
public string picture { get; set; }
You save your picture like this:
#using (Html.BeginForm("Create", "Photo", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.DisplayNameFor(model => model.PhotoFile)
<input type="file" name="Image" />
And the ActionResult method inside your PhotoController would be
public ActionResult Create(Photo photo, HttpPostedFileBase image)
{
and the actual saving of the photo itself
if (image != null)
{
photo.ImageFileName = image.FileName;
photo.ImageMimeType = image.ContentType;
photo.PhotoFile = new byte[image.ContentLength];
image.InputStream.Read(photo.PhotoFile, 0, image.ContentLength);
}
context.Add<Photo>(photo);
context.SaveChanges();
Hope you can connect the dots.
Mohammad
check your image folder permissions, If not, set it to all read, write, execute permissions. Try to debug the code and check whether the file is null or any exception fires while file.SaveAs called
Saving url into db is quite simple.At the same time you can save the picture in byte format in db.In your customer model you have
Method-1:
Change string type or any other type to byte.
So In this picture if you want to save the picture you convert picture to byte type instead of string in your customer table in db.
//before
[Display(Name = "Picture")]
public string picture { get; set; }
//After changing in db you add the table in entity framework .edmx and now it becomes
[Display(Name = "Picture")]
public byte[] picture { get; set; }
Here follows your code to save picture in byte format in db.
In your controller
public ActionResult Register(customer model)
{
string ImageName = Path.GetFileName(file.FileName);
string physicalPath = Server.MapPath("~/images/" + ImageName);
file.SaveAs(physicalPath);
customer newRecord = new customer ();
newRecord.username= customer.username;
\\Assign for remaining feilds in table in this way.
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
byte[] picArray = ms.GetBuffer();
newRecord.picture= picArray ;
}
onlinebookstoreEntities1 db = new onlinebookstoreEntities1();
db.customers.Add(newRecord);
db.SaveChanges();
}
In your Register View
<div>
#using (Html.BeginForm("ConfigAssetData", "Home", new { #tabno = "3" }, FormMethod.Post, new { enctype = "multipart/form-data", #class = "form-horizontal" }))
{
<div class="editor-label">
#Html.LabelFor(model => model.first_name)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.first_name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.last_name)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.last_name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.user_id)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.user_id)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.password)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.address)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.city)
</div>
<div class="txtreg">
#Html.EditorFor(model => model.city)
</div>
#*UploadFile*#
**<input type="file" class="file-input" name="file"/>**
#*Similar code here...*#
}
</div>
Method-2:
Especially in your case as you need to save picture path what you all need to do is:-
In your Controller
public ActionResult Register(customer model)
{
string ImageName = Path.GetFileName(file.FileName);
string physicalPath = Server.MapPath("~/images/" + ImageName);
file.SaveAs(physicalPath);
customer newRecord = new customer ();
newRecord.username= customer.username;
//.......saving picture url......
newRecord.picture = physicalPath;
//Assign for remaining feilds in table in this way.
onlinebookstoreEntities1 db = new onlinebookstoreEntities1();
db.customers.Add(newRecord);
db.SaveChanges();
}
If you right click on your images folder and click "Open folder in windows explorer" you can see your pic uploaded.
I try Create a new article in my table art, but the POST Method doesn't work, i don't now why, , Edit Article working perfectly, i read many post form that topic and nothing, i hope anyone can help me
Model
public class Art
{
[Key]
public int idArt { get; set; }
[DisplayName("Codigo Artículo")]
[Required(ErrorMessage = "Codigo Artículo Requerido")]
[MaxLength(30)]
public string co_art { get; set; }
[DisplayName("Tipo Articulo")]
[ForeignKey("TypeArticles")]
[Required(ErrorMessage = "Tipo Artículo Requerido")]
public int IDType { get; set; }
public virtual TypeArticles TypeArticles { get; set; }
[DisplayName("Descripción")]
[Required(ErrorMessage = "Descripción Artículo Requerido")]
[MaxLength(150)]
public string des_art { get; set; }
[DisplayName("Modelo")]
[Required(ErrorMessage = "Modelo Artículo Requerido")]
[MaxLength(50)]
public string modelo { get; set; }
[DisplayName("Referencia")]
[MaxLength(50)]
[Required(ErrorMessage = "Referencia Artículo Requerido")]
public string referencia { get; set; }
[DisplayName("Linea Artículo")]
[ForeignKey("Linea")]
[Required(ErrorMessage = "Linea Artículo Requerido")]
public int IdLinea { get; set; }
public virtual Linea Linea { get; set; }
[DisplayName("Categoria Artículo")]
[ForeignKey("Categoria")]
[Required(ErrorMessage = "Categoria Artículo Requerido")]
public int idCat { get; set; }
public virtual Categoria Categoria { get; set; }
[DisplayName("Precio Venta")]
[Range(0.01, 999999999, ErrorMessage = "Precio debe estar entre 0.01 y 999999999")]
public double Price { get; set; }
[MaxLength(1024)]
[DisplayName("Info. Adicional")]
public string Adicional { get; set; }
[MaxLength(100)]
public string Photo { get; set; }
}
Controller POST Method
[HttpPost]
[ValidateInput(false)]
public ActionResult Create(Art artmodels)
{
ViewBag.idLinea = new SelectList(db.Linea.OrderBy(c => c.des_lin), "IdLinea", "des_lin");
ViewBag.IdCat = new SelectList(db.Categorias.OrderBy(c => c.des_cat), "IdCat", "des_cat");
ViewBag.IDType = new SelectList(db.TypeArticles.OrderBy(c => c.TypeDesc), "IDType", "TypeDesc");
if (ModelState.IsValid)
{
var art_exists = (from inv in db.Art where inv.co_art == artmodels.co_art.Trim() select inv).FirstOrDefault();
if (art_exists != null)
{
ModelState.AddModelError("co_art", "Codigo de Articulo ya Existe");
return View(artmodels);
}
db.Art.Add(artmodels);
db.SaveChanges();
///
//int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
//var articulos = db.Art;
//IPagedList<Art> art_paged = null;
//art_paged = articulos.OrderBy(i => i.co_art).ToPagedList(currentPageIndex, (pagesize.HasValue) ? pagesize.Value : defaultPageSize);
return RedirectToAction("Edit", "Articulos", new {id = artmodels.idArt });
}
this.Response.StatusCode = 400;
return View(artmodels);
}
View
#model mvcAmerica.Models.Art
#{
ViewBag.Title = "Creacion";
}
<h1><small>Creación Articulos</small></h1>
#using (Html.BeginForm("Create", "Articulos", FormMethod.Post))
{
#Html.ValidationSummary(true)
<text>
#{Html.RenderPartial("CreateOrEditArticulos", Model);}
</text>
}
RenderPartial
#model mvcAmerica.Models.Art
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
#Html.HiddenFor(model => model.idArt)
<div class="clearfix">
#Html.LabelFor(model => model.co_art)
<div class="input">
#Html.EditorFor(model => model.co_art)
#Html.ValidationMessageFor(model => model.co_art)
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.des_art)
<div class="input">
#Html.EditorFor(model => model.des_art)
#Html.ValidationMessageFor(model => model.des_art)
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.IDType, "Tipo Articulo")
<div class="input chosen-select">
#Html.DropDownList("IDType", String.Empty)
#Html.ValidationMessageFor(model => model.IDType)
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.modelo)
<div class="input">
#Html.EditorFor(model => model.modelo)
#Html.ValidationMessageFor(model => model.modelo)
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.referencia)
<div class="input">
#Html.EditorFor(model => model.referencia)
#Html.ValidationMessageFor(model => model.referencia)
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.IdLinea)
<div class="input chosen-select">
#Html.DropDownList("IdLinea", String.Empty)
#Html.ValidationMessageFor(model => model.IdLinea)
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.idCat)
<div class="input chosen-select">
#Html.DropDownList("IdCat", String.Empty)
#Html.ValidationMessageFor(model => model.idCat)
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.Price)
<div class="input">
#Html.EditorFor(model => model.Price)
#Html.ValidationMessageFor(model => model.Price)
</div>
</div>
<div class="clearfix">
#Html.LabelFor(model => model.Adicional)
<div class="input">
#Html.EditorFor(model => model.Adicional)
#Html.ValidationMessageFor(model => model.Adicional)
</div>
</div>
<div class="actions">
<input type="submit" class="btn primary" value="Guardar" />
#Html.ActionLink("Listado", "Index", null, new { #class = "btn" })
</div>
</fieldset>
}
Thanks for the help that bring me in this problem...
You have nested forms in your code which is causing this issue. The Submit button is in the inner but it dies not have any Controller and Anction methods to call, So it's not post the data to any method.
So you need to change this code something like this:
View
#model mvcAmerica.Models.Art
#{
ViewBag.Title = "Creacion";
}
<h1><small>Creación Articulos</small></h1>
//the commented line should go to the partial view
//#using (Html.BeginForm("Create", "Articulos", FormMethod.Post))
//{
// #Html.ValidationSummary(true)
<text>
#{Html.RenderPartial("CreateOrEditArticulos", Model);}
</text>
RenderPartial
#model mvcAmerica.Models.Art
#using (Html.BeginForm("Create", "Articulos", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
// rest of the code is as it is
}
I have a form which has a ViewModel class underlaying it. I have set the [Required] validation on fields of the form. The form still submits even though it does for a moment - before it submits - displays the ErrorMessage set on particular fields.
There is no validation on the StockReceipt model itself, but only the ViewModel. I looked at this question here and learnt that validating the model is optional.
I wonder why the form still submits when there are invalid input?
Here is my View and ViewModel code:
View:
#using (Html.BeginForm("SaveSettings", "StockReceipt", FormMethod.Post,
new { id = "StockReceiptForm", enctype = "multipart/form-data" }))
{
<fieldset>
<div>
#* #Html.ValidationSummary(false)*#
<legend>Stock-Receipt Details</legend>
#*#if (User.IsInRole(Constants.Super))
{*#
<div style="display: none;">
Delivery Note Ref
</div>
<div style="display: none;">
#Html.TextBoxFor(model => model.StockReceiptID, new { #Class = "k-textbox" })
</div>
<div class="editor-label">
Supplier
</div>
<div class="editor-field">
#Html.Kendo().DropDownListFor(model => model.SupplierID).BindTo(Model.SuppliersList).DataTextField("Name").DataValueField("SupplierID").OptionLabel("Select")
#Html.ValidationMessageFor(model => model.SupplierID)
</div>
<div class="editor-label">
Material
</div>
<div class="editor-field">
#Html.Kendo().DropDownListFor(model => model.MaterialID).BindTo(Model.MaterialsList).DataTextField("Name").DataValueField("MaterialID").OptionLabel("Select")
#Html.ValidationMessageFor(model => model.MaterialID)
</div>
<div class="editor-label">
Qty
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Quantity, new { #Class = "k-textbox" })
#Html.ValidationMessageFor(model => model.Quantity)
</div>
<div class="editor-label">
Of which reserved
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.QuantityReserved, new { #Class = "k-textbox" })
</div>
<div class="editor-label">
Units
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.NumberOfUnits, new { #Class = "k-textbox" })
#(Html.Kendo().DropDownListFor(model => model.StockUnitsEnum).Name("StockUnitsEnum")
.BindTo(Enum.GetValues(typeof(StockUnitsEnum))
.Cast<StockUnitsEnum>()
.Select(p => new SelectListItem
{
Text = p.ToString(),
Value = ((int)p).ToString(CultureInfo.InvariantCulture)
})
.ToList())
)
#Html.ValidationMessageFor(model => model.NumberOfUnits)
</div>
<div class="editor-label">
Batch Reference:
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.BatchReference, new { #Class = "k-textbox" })
#Html.ValidationMessageFor(model => model.BatchReference)
</div>
<div class="editor-label">
Slab Width
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.SlabWidth, new { #Class = "k-textbox" }) x #Html.TextBoxFor(model => model.SlabHeight, new { #Class = "k-textbox" })
</div>
<div class="editor-label">
Include Transport:
</div>
<div class="editor-field">
#Html.CheckBoxFor(model => model.IncludeTransport)
</div>
<div class="editor-label">
Notes
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.Notes, new { #Class = "k-textbox" })
</div>
<div class="clear">
Totals
</div>
<div class="editor-label">
Unit Cost
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.UnitCost, new { #Class = "k-textbox" })
#Html.ValidationMessageFor(model => model.UnitCost)
</div>
<div class="editor-label">
Units
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.NumberOfUnits, new { #Class = "k-textbox" })
#Html.ValidationMessageFor(model => model.NumberOfUnits)
</div>
<div class="editor-label">
Slab Cost
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.SlabCost, new { #Class = "k-textbox" })
#Html.ValidationMessageFor(model => model.SlabCost)
</div>
<div class="editor-label">
Location
</div>
<div class="editor-field">
#Html.Kendo().DropDownListFor(model => model.LocationID).BindTo(Model.LocationsList).DataTextField("Name").DataValueField("LocationID").OptionLabel("Select")
</div>
<div class="editor-label">
Purchase-Order Ref.
</div>
<div class="editor-field">
#Html.Kendo().DropDownListFor(model => model.PurchaseOrderID).BindTo(Model.PurchaseOrdersList).DataTextField("PONumber").DataValueField("PurchaseOrderID").OptionLabel("Select")
#Html.ValidationMessageFor(model => model.PurchaseOrdersList)
</div>
<div class="editor-label">
Invoice Ref.
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.InvoicNo, new { #Class = "k-textbox" })
#Html.ValidationMessageFor(model => model.InvoicNo)
</div>
<br />
<div class="editor-label">
</div>
<div class="editor-field">
<input type="submit" value="Save" class="k-button" />
</div>
</div>
</fieldset>
}
ViewModel:
public class StockReceiptViewModel
{
public int StockReceiptID { get; set; }
[Required(ErrorMessage = "Required")]
public int SupplierID { get; set; }
[Required(ErrorMessage = "Required")]
public int MaterialID { get; set; }
[Required(ErrorMessage = "Required")]
public DateTime? ReceiptDate { get; set; }
[Required(ErrorMessage = "Required")]
public int Quantity { get; set; }
public int? QuantityReserved { get; set; }
[Required(ErrorMessage = "Required")]
public decimal? SlabWidth { get; set; }
[Required(ErrorMessage = "Required")]
public decimal? SlabHeight { get; set; }
[Required(ErrorMessage = "Required")]
public int SizeUnits { get; set; }
[Required(ErrorMessage = "Required")]
public StockUnitsEnum StockUnitsEnum
{
get {return (StockUnitsEnum)SizeUnits;}
set {SizeUnits = (int)value;}
}
[Required(ErrorMessage = "Required")]
public string BatchReference { get; set; }
[Required(ErrorMessage = "Required")]
[DataType(DataType.Currency)]
public decimal? UnitCost { get; set; }
[Required(ErrorMessage = "Required")]
public int? NumberOfUnits { get; set; }
[Required(ErrorMessage = "Required.")]
public int PurchaseOrderID { get; set; }
[Required(ErrorMessage = "Required")]
public string InvoicNo { get; set; }
[Required(ErrorMessage = "Required")]
public decimal SlabCost { get; set; }
public bool IncludeTransport { get; set; }
[Required(ErrorMessage = "Required.")]
public int LocationID { get; set; }
public int? EnteredBy { get; set; }
public DateTime OnSystemFrom { get; set; }
public string Notes { get; set; }
public List<SupplierViewModel> SuppliersList { get; set; }
public List<MaterialViewModel> MaterialsList { get; set; }
public List<LocationsViewModel> LocationsList { get; set; }
public List<PurchaseOrderViewModel> PurchaseOrdersList { get; set; }
public int LastModifiedBy { get; set; }
public DateTime LastModifiedDate { get; set; }
public int LiveQuantity { get; set; }
}
The Controller method has the ModelState.Isvalid check as well.
Please help if you can.
Many thanks.
You need to add jquery.unobtrusive and jquery.validate files to your views. Add this to your BundleConfig.cs:
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
And then render it on your _Layout View or in View you want validation:
#Scripts.Render("~/bundles/jqueryval")
If you are using default MVC template you should already have this bundle. Just make sure you have reference in your Views. You can check if your js files are loaded by using some web development tools like Firebug in Mozzila or press F12 in Chrome, and in NET tab you can see loaded scripts.
I have solved this problem by making sure that the method to where this form is submitting, is returning the viewmodel to the page (view) if ModelState.IsValid is false.
This is provided that the viewModel being returned is actually the same as the submitted one:
[HttpPost]
public ActionResult SaveSettings(StockReceiptViewModel stockReceiptVm)
{
try
{
if (ModelState.IsValid)
{
var stockReceipt = new StockReceipt();
if (stockReceiptVm.StockReceiptID != 0)
{
MapViewModelToModel(stockReceiptVm, stockReceipt);
stockReceipt.LastModifiedBy = UserHelper.GetCurrentUserIDByEmail();
stockReceipt.LastModifiedDate = DateTime.Now;
//update
_stockReceiptRepository.UpdateStockReceipt(stockReceipt, stockReceiptVm.StockReceiptID);
}
else
{
MapViewModelToModel(stockReceiptVm, stockReceipt);
stockReceipt.EnteredBy = UserHelper.GetCurrentUserIDByEmail();
stockReceipt.OnSystemFrom = Utilities.RemoveTimeFromDate(DateTime.Now);
//save new
_stockReceiptRepository.InsertStockReceipt(stockReceipt);
}
return RedirectToAction("Index", "StockReceiptsGrid");
}
SetupViewDropdownLists(stockReceiptVm);
return View("Index", stockReceiptVm);
}
catch (Exception exc)
{
ErrorHelper.WriteToEventLog(exc);
return RedirectToAction("Index", "Error");
}
}
I've just created a new controller, along with its CRUD forms, etc, with a database-first EF model/entity.
Its throwing a number of validation errors on save, but since the form has validators, I don't see why this would be so.
For reasons that are beyond me, I'm not getting any validation to happen at all. It just goes right in to the saveChanges() call, which promptly fails.
Here's the edit form:
#model StatementsApplication.DAL.StatementTask
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>StatementTask</legend>
<div class="editor-label">
#Html.LabelFor(model => model.sInitials)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.sInitials)
#Html.ValidationMessageFor(model => model.sInitials)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.dtCompleted)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.dtCompleted)
#Html.ValidationMessageFor(model => model.dtCompleted)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.sGroupLabel)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.sGroupLabel)
#Html.ValidationMessageFor(model => model.sGroupLabel)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.nGroupSequence)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.nGroupSequence)
#Html.ValidationMessageFor(model => model.nGroupSequence)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.sTaskType)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.sTaskType)
#Html.ValidationMessageFor(model => model.sTaskType)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.sTaskLabel)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.sTaskLabel)
#Html.ValidationMessageFor(model => model.sTaskLabel)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.nTaskSequence)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.nTaskSequence)
#Html.ValidationMessageFor(model => model.nTaskSequence)
</div>
#Html.HiddenFor(model => model.ID)
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
and here's the generated model:
namespace StatementsApplication.DAL
{
using System;
using System.Collections.Generic;
public partial class StatementTask
{
public int StmtBatchID { get; set; }
public string sInitials { get; set; }
public Nullable<System.DateTime> dtCompleted { get; set; }
public string sGroupLabel { get; set; }
public double nGroupSequence { get; set; }
public string sTaskType { get; set; }
public string sTaskLabel { get; set; }
public double nTaskSequence { get; set; }
public int ID { get; set; }
public virtual StatementBatch tblStmtBatch { get; set; }
}
}
and here's the controller bits...
//
// GET: /StatementTask/Edit/5
public ActionResult Edit(int id = 0)
{
StatementTask statementtask = db.StatementTasks.Find(id);
if (statementtask == null)
{
return HttpNotFound();
}
ViewBag.StmtBatchID = new SelectList(db.StatementBatches, "ID", "sStatus", statementtask.StmtBatchID);
return View(statementtask);
}
//
// POST: /StatementTask/Edit/5
[HttpPost]
public ActionResult Edit(StatementTask statementtask)
{
if (ModelState.IsValid)
{
try
{
db.Entry(statementtask).State = EntityState.Modified;
db.SaveChanges();
}
catch (Exception ex) {
throw ex;
}
return RedirectToAction("Index");
}
ViewBag.StmtBatchID = new SelectList(db.StatementBatches, "ID", "sStatus", statementtask.StmtBatchID);
return View(statementtask);
}
Its a matter of some confusion for me as to why sInitials is throwing 'required' validation errors, as well as why sGroupLabel is throwing length validation errors.
Thanks
a) your model has no data validation annotations. As such, MVC doesn't do any validation, because you're not telling it what to validate.
b) You don't mention what you are submitting. Are you just submitting an empty form?
it appears that Data Annotations will resolve this issue
[Required(AllowEmptyStrings = true)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public object Note { get; set; }
via http://fendy-huang.blogspot.com/2011/04/how-to-pass-empty-string-in-entity.html