ASP Net MVC - Forms Validation on the ViewModel - asp.net-mvc

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");
}
}

Related

validations error messages not showing on the view

I have implemented a mvc kendo window control in my MVC page and the form validation doenst seem to work. I can the model state as false in the controller but the view doesnt seem showing the messages. Please note here that WorkLogType,WorkLog Subject and Details are required field. I have set the required attribute in the view model. I have also set the validation tag in the view for the respective controls. What is the problem ?
Here is my code
View
#using (Ajax.BeginForm("ActivityWorkLog_Create", "Activity", new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "OnSuccess",
OnFailure = "OnFailure"
}))
{
<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.WorkLogType)
.Name("WorkLogTypeCode")
.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.WorkLogType, "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="statusMessage"> </div>
</div>
</div>
}
ViewModel
public class ActivityWorkLogViewModel
{
[ScaffoldColumn(false)]
[Display(Name = "WorkLogID", ResourceType = typeof(Resources.Resource))]
public int WorkLogID { get; set; }
[Required]
[Display(Name = "WorkLogTypeCode", ResourceType = typeof(Resources.Resource))]
public string WorkLogTypeCode { get; set; }
[Display(Name = "WorkLogType", ResourceType = typeof(Resources.Resource))]
[Required(ErrorMessage = "WorkLogType is required")]
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; }
}
Controller
[HttpPost]
public ActionResult ActivityWorkLog_Create(ActivityWorkLogViewModel workLogViewModel)
{
if (!ModelState.IsValid)
{
return View("EditorTemplates/_WorkLogEdit", Mapper.Map<ActivityWorkLogViewModel>(workLogViewModel));
}
WorkLogRepository workLogRepository = new WorkLogRepository();
workLogRepository.CreateWorkLog(Mapper.Map<WorkLog>(workLogViewModel));
return PartialView("EditorTemplates/_WorkLogEdit", Mapper.Map<ActivityWorkLogViewModel>(workLogViewModel));
}
Bundle.config
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery-ui-1.12.1.min.js",
"~/Scripts/jquery.validate.min.js",
"~/Scripts/jquery.validate.unobtrusive.min.js"
));
Add these lines in your view:
<script>
$(document).ready(function() {
var form = $('form') // Give Id prop to your from
.removeData("validator")
.removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse(form);
});
<script>
Also make sure you add jquery.validate.js and jquery.validate.unobtrusive.js into your View cshtml for validation to work properly.

DropDownListFor in MVC 4

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.

POST Method doesn't work MVC 4

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
}

Using one html.editorfor to fill in two model fields

Im trying to use only 1 html.editorfor to fill in two model field in each of my model.
I want the value of this editorfor to be also inserted to my Clientes0013.Client0013
<div class="editor-field">
#Html.EditorFor(model => model.CanaClie0012.Client00130012)
#Html.ValidationMessageFor(model => model.CanaClie0012.Client00130012)
</div>
and this one to be also inserted to Clientes0013.F1Pais00200013
<div class="editor-field">
#Html.EditorFor(model => model.CanaClie0012.F1Pais00200012)
#Html.ValidationMessageFor(model => model.CanaClie0012.F1Pais00200012)
</div>
Kindly show me what should be the right way of doing this.
My Table Model:
public partial class CanaClie0012
{
public string Client00130012 { get; set; }
public string F1Pais00200012 { get; set; }
public string F1Cana02530012 { get; set; }
public string Direcc0012 { get; set; }
public Nullable<System.DateTime> TmStmp0012 { get; set; }
}
public partial class Clientes0013
{
public string Client0013 { get; set; }
public string Nombre0013 { get; set; }
public string F1Pais00200013 { get; set; }
}
My Custom Model to combine the two table is:
public class ClientModel
{
public CanaClie0012 CanaClie0012 { get; set; }
public Clientes0013 Clientes0013 { get; set; }
}
My Controller:
[HttpPost]
public ActionResult ClientCreate(CanaClie0012 canaclie0012, Clientes0013 clientes0013)
{
ClientModel vm = new ClientModel();
if (ModelState.IsValid)
{
db.CanaClie0012.Add(canaclie0012);
db.Clientes0013.Add(clientes0013);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vm);
}
My View:
#model MvcApplication1.Models.ClientModel
#{
ViewBag.Title = "ClientCreate";
}
<h2>ClientCreate</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>ClientModel</legend>
<div class="editor-label">
Client Name
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CanaClie0012.Client00130012)
#Html.ValidationMessageFor(model => model.CanaClie0012.Client00130012)
</div>
<div class="editor-label">
Pais
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CanaClie0012.F1Pais00200012)
#Html.ValidationMessageFor(model => model.CanaClie0012.F1Pais00200012)
</div>
<div class="editor-label">
Address
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CanaClie0012.Direcc0012)
#Html.ValidationMessageFor(model => model.CanaClie0012.Direcc0012)
</div>
<div class="editor-label">
Contact Number
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Clientes0013.Nombre0013)
#Html.ValidationMessageFor(model => model.Clientes0013.Nombre0013)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Got it.. modified my controller action to this one.
[HttpPost]
public ActionResult ClientCreate(CanaClie0012 canaclie0012, Clientes0013 clientes0013)
{
ClientModel vm = new ClientModel();
if (ModelState.IsValid)
{
clientes0013.Client0013 = canaclie0012.Client00130012;
clientes0013.F1Pais00200013 = canaclie0012.F1Pais00200012;
db.CanaClie0012.Add(canaclie0012);
db.Clientes0013.Add(clientes0013);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vm);
}

Adding Foreign key value from dropdown box / data not showing in dropdown

I am working with a create method for my renter controller. Each new renter has a corresponding building that its attached to. I want it so that in my create view it shows the buildings name and then populates the table with its corresponding id. I cannot figure out how to get this to work.
public class Renter
{
[Key]
public int RenterId { get; set; }
public int BuildingID { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
[DataType(DataType.PhoneNumber)]
public String Phone { get; set; }
[DataType(DataType.EmailAddress)]
public String Email { get; set; }
public Boolean IsApproved { get; set; }
//Foreign Key
// [Required]
public virtual Building Building { get; set; }
}
public class Building
{
[Key]
public int BuildingId { get; set; }
public string BuildingName { get; set; }
public virtual ICollection<Renter> Residents { get; set; }
public int ManagerId { get; set; }
public virtual Manager Manager { get; set; }
}
public class Manager
{
[Key]
public int ManagerId { get; set; }
public virtual ICollection<Renter> Tenants { get; set; }
public virtual ICollection<Building> Buildings { get; set; }
}
Create view
#model RPMS.Models.Renter
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Renter</legend>
<div class="editor-label">
#Html.LabelFor(model => model.BuildingID, "Building")
</div>
<div class="editor-field">
#Html.DropDownList("BuildingID", String.Empty)
#Html.ValidationMessageFor(model => model.BuildingID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Phone)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Phone)
#Html.ValidationMessageFor(model => model.Phone)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.IsApproved)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.IsApproved)
#Html.ValidationMessageFor(model => model.IsApproved)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Currently when I run this and go to select the building, nothing shows up in the dropdown box even though I have initialized the data
protected override void Seed(RPMSContext context)
{
var renters = new List<Renter>
{
new Renter {RenterId = 1, BuildingID = 1, FirstName="Bradley", LastName="Woods",Phone="614-218-0294", Email="bradleydeanwoods#gmail.com",IsApproved = true},
};
renters.ForEach(s => context.Renters.Add(s));
context.SaveChanges();
var buildings = new List<Building>
{
new Building {BuildingId = 1, BuildingName="Annex at River South",ManagerId = 1},
};
buildings.ForEach(s => context.Buildings.Add(s));
context.SaveChanges();
var managers = new List<Manager>
{
new Manager {ManagerId = 1,},
};
managers.ForEach(s => context.Managers.Add(s));
context.SaveChanges();
}
And finally here is the DbContext
public class RPMSContext : DbContext
{
public DbSet<Renter> Renters { get; set; }
public DbSet<Building> Buildings { get; set; }
public DbSet<Manager> Managers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
Thanks for your help in advance for helping me to get past this sticking point.
Update The seed data shows when I take out the foreign key relationships so that is what I have done for now and just decided to move on.

Resources