Update user Profile in asp.net mvc model is not valid - c#

I'm a beginner to ASP.NET MVC.
I want to update login user profile and I am having a problem. my code says model state is not valid. I've tried every possible solution which I know and also searched on Google.
I'm using Entity Framework and below is my code.
Table name: Userdb
Get action method in the controller:
public ActionResult EditProfile()
{
string username = User.Identity.Name;
Userdb user = db.Userdbs.FirstOrDefault(u => u.u_Email.Equals(username));
Userdb model = new Userdb();
// Personal Details
model.u_Firstname = user.u_Firstname;
model.u_lastname = user.u_lastname;
model.u_dob = user.u_dob;
model.u_mobile = user.u_mobile;
model.u_title = user.u_title;
// this to display data in texbox
ViewBag.u_Email = user.u_Email;
ViewBag.u_Firstname = user.u_Firstname;
ViewBag.u_lastname = user.u_lastname;
ViewBag.u_dob = user.u_dob;
ViewBag.u_mobile = user.u_mobile;
ViewBag.u_title = user.u_title;
// Education Details
model.Degree_level = user.Degree_level;
model.Degree_name = user.Degree_name;
model.Starting_date = user.Starting_date;
model.Completion_date = user.Completion_date;
// Address Details
model.country_name = user.country_name;
model.city_name = user.city_name;
model.Address = user.Address;
model.postal_code = user.postal_code;
// Social Link Details
model.S_fb_url = user.S_fb_url;
model.S_linkedin_url = user.S_linkedin_url;
model.S_github_url = user.S_github_url;
model.S_twitter_url = user.S_twitter_url;
return View(model);
}
Post action method in controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditProfile(Userdb editEntity)
{
if (ModelState.IsValid)
{
string username = User.Identity.Name;
// Get the userprofile
Userdb model =new Userdb();
// Personal Details
model.u_Firstname = editEntity.u_Firstname;
model.u_lastname = editEntity.u_lastname;
model.u_dob = editEntity.u_dob;
model.u_mobile = editEntity.u_mobile;
model.u_title = editEntity.u_title;
ViewBag.u_Email = editEntity.u_Email;
ViewBag.u_Firstname = editEntity.u_Firstname;
ViewBag.u_lastname = editEntity.u_lastname;
ViewBag.u_dob = editEntity.u_dob;
ViewBag.u_mobile = editEntity.u_mobile;
ViewBag.u_title = editEntity.u_title;
// Education Details
model.Degree_level = editEntity.Degree_level;
model.Degree_name = editEntity.Degree_name;
model.Starting_date = editEntity.Starting_date;
model.Completion_date = editEntity.Completion_date;
// Address Details
model.country_name = editEntity.country_name;
model.city_name = editEntity.city_name;
model.Address = editEntity.Address;
model.postal_code = editEntity.postal_code;
// Social Link Details
model.S_fb_url = editEntity.S_fb_url;
model.S_linkedin_url = editEntity.S_linkedin_url;
model.S_github_url = editEntity.S_github_url;
model.S_twitter_url = editEntity.S_twitter_url;
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index", "Home"); // or whatever
}
return View();
}
View
#model Applicant.Models.Userdb
#{
ViewBag.Title = "EditProfile";
Layout = "~/Views/Shared/_ProfileLayout.cshtml";
}
#using (Html.BeginForm("EditProfile", "Users"))
{
#Html.AntiForgeryToken()
<body>
<div class="container rounded bg-white mt-5 mb-5">
<div class="row">
<div class="col-md-3 border-right">
<div class="d-flex flex-column align-items-center text-center p-3 py-5"><img class="rounded-circle mt-5" width="150px" src="https://st3.depositphotos.com/15648834/17930/v/600/depositphotos_179308454-stock-illustration-unknown-person-silhouette-glasses-profile.jpg"><span class="font-weight-bold">#ViewBag.u_Firstname #ViewBag.u_lastname</span><span class="text-black-50">#ViewBag.u_Email</span><span> </span></div>
</div>
<div class="col-md-5 border-right">
<div class="p-3 py-5">
<div class="d-flex justify-content-between align-items-center mb-3">
<h4 class="text-right">Profile Settings</h4>
</div>
<h6>Personal Detail</h6>
<div class="row mt-2">
<div class="col-md-6"><label class="labels">Name</label>#Html.EditorFor(model => model.u_Firstname, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_Firstname } })</div>
<div class="col-md-6"><label class="labels">Lastname</label>#Html.EditorFor(model => model.u_lastname, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_lastname } })</div>
</div>
<div class="row mt-2">
<div class="col-md-6">
<label class="labels">Gender</label><br />
#Html.RadioButtonFor(model => model.u_Gender, "F")
Female
#Html.RadioButtonFor(model => model.u_Gender, "M")
Male
</div>
<div class="col-md-6"><label class="labels">Designation</label>#Html.EditorFor(model => model.u_title, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_title } })</div>
</div>
<div class="row mt-3">
<div class="col-md-12"><label class="labels">Mobile Number</label>#Html.EditorFor(model => model.u_mobile, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_mobile } })</div>
<div class="col-md-12"><label class="labels">Address</label>#Html.EditorFor(model => model.Addres, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Addres } })</div>
<div class="col-md-12"><label class="labels">Country</label>#Html.EditorFor(model => model.country_name, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.country_name } })</div>
</div>
<div class="row mt-2">
<div class="col-md-6"><label class="labels">City</label>#Html.EditorFor(model => model.city_name, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.city_name } })</div>
<div class="col-md-6"><label class="labels">Postal Code</label>#Html.EditorFor(model => model.postal_code, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.postal_code } })</div>
</div>
<hr />
<h6>Education Detail</h6>
<div class="row mt-3">
<div class="col-md-12"><label class="labels">Degree Name</label>#Html.EditorFor(model => model.Degree_name, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Degree_name } })</div>
<div class="col-md-12"><label class="labels">Degree Level</label>#Html.EditorFor(model => model.Degree_level, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Degree_level } })></div>
</div>
<div class="row mt-2">
<div class="col-md-6"><label class="labels">Starting Date</label>#Html.EditorFor(model => model.Starting_date, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Starting_date } })</div>
<div class="col-md-6"><label class="labels">Completion Date</label>#Html.EditorFor(model => model.Completion_date, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Completion_date } })</div>
</div>
<hr />
<div class="mt-5 text-center">
<input type="submit" value="Save Changes" class="btn" style="background-color:#5777ba; color:#fff;" />
</div>
</div>
</div>
<div class="col-md-4">
<div class="py-5">
<h6>Skills Detail</h6>
<div class="col-md-12"><label class="labels">Skills</label><input type="text" class="form-control" placeholder="experience" value=""></div>
</div>
<div class="">
<h6>Skills Detail</h6>
<div class="col-md-12"><label class="labels">Github Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
<div class="col-md-12"><label class="labels">Linkedin Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
<div class="col-md-12"><label class="labels">Twitter Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
<div class="col-md-12"><label class="labels">Facebook Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
</div>
</div>
</div>
</div>
</body>
}

There are several problems with your view, which could account for the invalid model. If you post the definition of Userdb, complete with any metadata class (if those are still being used) we could see for sure.
First, you aren't putting the necessary name attribute in all your plain input fields. This means they won't get posted to the server as data, so the model binder won't be able to automatically populate those fields in your model.
Second, you've used #Html.EditorFor() in several places, with the identical properties being referenced. This means that what you put in the text box labeled "Name" will be assigned to the u_Firstname field on your model -- but so will what you've put in the "Gender" and "City" fields!
That means that the actual Gender and City properties on your model won't be populated.
Third, you say u_Email is the primary key, but it isn't even posted back from this form.
This brings me to what I suspect the real source of the problem is: your model isn't being fully populated from the form on posting, because you're not collecting all the data. And I'd guess at least some of those properties have Required or other constraints on them that mean leaving them empty isn't allowed. (u_Email is a likely candidate, since it's the primary key.)
If you look at the contents of editEntity while debugging, it will probably be made very clear what's populated and what isn't.

replace this code
db.Entry(model).State = EntityState.Modified;
with
db.Entry(model).State = System.Data.Entity.EntityState.Modified;
the above whole code is true but the main problem is when you change the state of entity EntityState.Modified should be replaced with System.Data.Entity.EntityState.Modified; because EntityState is an object of System.Data.Entity* namespace

Related

Can't load image to partial view in edit view

In my application, previously I had issue with loading data to the partial view. With help I resolved that it. But still there is some issue here. Now when create the request I use this partial view to add data and image for user.
#model Asp_PASMVC.Models.GeneralItms
#using Asp_PASMVC.Infrastructure
#{
var z = Model.Attachment_Description;
var a = Model.Attachment_Amount;
var x = Model.Attachment;
}
<li style="padding-bottom:15px">
#using (Html.BeginCollectionItem("GeneralItmsList"))
{
#Html.HiddenFor(model => model.TempID)
<div class="form-horizontal" id="quickForm" novalidate="novalidate">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
<div class="col-md-5 col-sm-6">
<div class="form-group">
Select Item Description
<div class="col-md-10">
#Html.EditorFor(model => model.Attachment_Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Attachment_Description, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col-md-3 col-sm-6">
<div class="form-group">
Attachment Amount
<div class="col-md-10">
<div class="input-group-prepend">
<span class="input-group-text">Rs.</span>
#Html.EditorFor(model => model.Attachment_Amount, new { htmlAttributes = new { #class = "form-control" } })
</div>
#Html.ValidationMessageFor(model => model.Attachment_Amount, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col-md-3 col-sm-6">
<div class="form-group">
Attachment
<div class="col-md-10">
<input type="file" name="ImageData#(Model.TempID.ToString())" id="ImageData#(Model.TempID.ToString())" multiple="multiple" data-id="Img#(Model.TempID.ToString())" onchange="checkImage(this)" />
#Html.ValidationMessageFor(model => model.Attachment, "", new { #class = "text-danger" })
</div>
</div>
<img id="Img#(Model.TempID.ToString())" src="" alt="" width="100" height="100" class="ml-1" />
</div>
<button type="button" class="btn btn-danger" onclick="$(this).parent().remove();">Remove</button>
</div>
</div>
}
</li>
<script type="text/javascript">
$('.js-dropdown').select2({
width: '100%', // need to override the changed default
});
function checkImage(obj) {
var fileExtension = ['jpeg', 'jpg', 'png', 'gif', 'bmp'];
var ResponceImgId = $(obj).data('id');
if ($.inArray($(obj).val().split('.').pop().toLowerCase(), fileExtension) == -1) {
alert('error', 'Upload Error', 'Only .jpeg, .jpg, .png, .gif, .bmp formats are allowed.');
}
else {
var files = obj.files;
var reader = new FileReader();
name = obj.value;
reader.onload = function (e) {
$('#' + ResponceImgId).prop('src', e.target.result);
};
reader.readAsDataURL(files[0]);
}
}
</script>
When creating the request in the controller I have code like this
if (appRequest.GeneralItmsList != null)
{
foreach (GeneralItms item in appRequest.GeneralItmsList)
{
HttpPostedFileBase file = Request.Files["ImageData" + item.TempID];
item.Attachment = ConvertToBytes(file);
}
appRequest.General = new List<General>()
{
new General
{
GeneralItms = appRequest.GeneralItmsList,
}
};
}
and this method will convert the image to byte and pass to the controller to submit the data.
public ActionResult RetrieveImageG(int id)
{
var q = from temp in db.GeneralItms where temp.Id == id select temp.Attachment;
byte[] cover = q.First();
if (cover != null)
{
return File(cover, "image/jpg");
}
else
{
return null;
}
}
So Crete is working fine, and when in the edit view, I again called the same partial view to load the data inside the edit main view.
It's has 3 fields. Item Description , Amount and the attachment.
So It's loading the Item Description and amount properly, and it won't load the image again. Within the partial view I have put
#{
var z = Model.Attachment_Description;
var a = Model.Attachment_Amount;
var x = Model.Attachment;
}
to check is data passing to the view. attachment is shown in the Model.Attachment. But it won't show in the view. Can I get a help on this?
if you already happen to have the image loaded in your model: doing this way you can display the image
<img src="data:image;base64,#System.Convert.ToBase64String(Model.Attachment)" />

c# - Ajax.BeginForm - 500 Error - Resource cannot found

I'm trying to submit my form using Ajax.beginform. I tried everything but i am getting this resource cannot found error.
I have two models - PatientEligibility and PatientDetails. Both contains 10-12 properties respectively.
I have created on viewmodel using those two models and I am trying to use some of the properties in one partial view and submitting that data button click
my view -
#model Portal.Models.EligibilityViewModel
<script type="text/javascript">
$(document).ready(function () {
$('input[type="checkbox"]').on('change', function () {
$('input[name="' + this.name + '"]').not(this).prop('checked', false);
});
});
</script>
<div class="row margin-top-0">
<div class="col-xs-12 col-sm-12">
<h4><b>Patient Eligibility</b></h4>
</div>
</div>
#using (Ajax.BeginForm("SubmitPatientEligibility", "Ophthalmic", new AjaxOptions { OnSuccess = "OnSuccess", OnFailure = "OnFailure" }))
{
<div class="row margin-top-10">
<div class="col-xs-12 col-sm-12">
<div class="margin-top-10">
<div class="checkbox">
<label>
#Html.CheckBoxFor(model => model.PatientEligibility.IsAboveSixty, new { #Name = "cbAgeEligibility", htmlAttributes = new { id = "cbAbvSixty", #class = "form-control", Name = "group1[]" } })
The patient is 60 or over
</label>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12">
<div class="margin-top-10">
<div class="checkbox">
<label>
#Html.CheckBoxFor(model => model.PatientEligibility.IsBelowSixteen, new { #Name = "cbAgeEligibility", htmlAttributes = new { id = "cbUnderSixteen", #class = "form-control", Name = "group1[]" } })
The patient is under 16
</label>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12">
<div class="margin-top-10">
<div class="checkbox">
<label>
#Html.CheckBoxFor(model => model.PatientEligibility.IsBetweenForty, new { #Name = "cbAgeEligibility", htmlAttributes = new { id = "cbAbovenForty", #class = "form-control", Name = "group1[]" } })
The patient is 40 or over and is the parent/brother/sister/child of a person who has or has had gloucoma
</label>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12">
<div class="margin-top-10">
<div class="checkbox">
<label>
#Html.CheckBoxFor(model => model.PatientEligibility.IsStudent, new { #Name = "cbAgeEligibility", htmlAttributes = new { id = "cbStudent", #class = "form-control", Name = "group1[]" } })
The patient is full time student aged 16, 17 or 18 at the establishment below.
</label>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12">
<div class="margin-top-10">
<div class="checkbox">
<label>
#Html.CheckBoxFor(model => model.PatientEligibility.IsPrisoner, new { data_toggle = "collapse", data_target = "#dvseenNotseen", htmlAttributes = new { id = "cbPrisoner", #class = "form-control" } })
The patient is prisoner on leave from the prison detailed below
</label>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12">
<div class="margin-top-10">
#Html.LabelFor(p => p.PatientBenefit.NINNumber)
#Html.EditorFor(model => model.PatientBenefit.NINNumber, new { htmlAttributes = new { #class = "form-control", autocomplete = "off" } })
</div>
</div>
<div class="col-xs-12 col-sm-12">
<div class="margin-top-10">
<label>DATE OF BIRTH</label>
#Html.TextBoxFor(model => model.PatientBenefit.DOB, new { #class = "form-control", autocomplete = "off", #id = "datetimepicker1" })
</div>
</div>
<div class="row margin-top-10">
<div class="col-xs-12 col-sm-3">
<button class="btn btn-default" name="btnBack">Previous</button>
</div>
<div class="col-xs-12 col-sm-9 text-right">
<button class="btn btn-default" name="btnBack">Save Draft</button>
<button class="btn btn-success fa fa-chevron-right icon-right" name="btnNext" type="submit">Next</button>
</div>
</div>
}
and my model is like this -
public class EligibilityViewModel
{
public PatientEligibility PatientEligibility { get; set; }
public PatientBenefit PatientBenefit { get; set; }
}
I am trying to call this method on submit of Next button -
public class OphthalmicController : Controller
{
[HttpPost]
public ActionResult SubmitPatientEligibility(EligibilityViewModel model)
{
return null;
}
}
i dont know why but i am getting this 500 error resource cannot found for this method.
What am I missing here?

How to pass dropdown value to controller in mvc? [duplicate]

This question already has answers here:
How to get DropDownList SelectedValue in Controller in MVC
(9 answers)
Closed 5 years ago.
I am working on bulk sms in mvc. I have a view named SendSMS where i have fields like Sender ID, Numbers, Messagetext. Here, I am getting value of SenderID from Sender table where it consists Sender ID, Sender Name. Before sending message, user will add Sender Name from different view. As of now, I have added Sender Name. I am able to display Sender Name using dropdownList in SendSMS view.
After creating Sender ID and Sender Name, User enters SendSMS view to send Message. User will select Sender Name using dropdown list. He will add Numbers and Message text. When user clicks on Send button, the dropdown value is to passing to controller.
Here is the view code:
#using (Html.BeginForm("SendMessage", "SendSMS", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Compose New Message</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(Model => Model.SendSMSModel.SenderType, new { #class = "form-control-label" })
<div class="input-group">
<span class="input-group-addon input_email">
<i class="fa fa-user text-primary"></i>
</span>
#Html.EnumDropDownListFor(Model => Model.SendSMSModel.SenderType, new { #class = "form-control form-control-md" })
#Html.ValidationMessageFor(Model => Model.SendSMSModel.SenderType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(Model => Model.SendSMSModel.SenderId, new { #class = "form-control-label" })
<div class="input-group">
<span class="input-group-addon input_email">
<i class="fa fa-sort-numeric-asc text-primary"></i>
</span>
#Html.DropDownList("SenderId", new SelectList(ViewBag.SenderNameList, "SenderId", "SenderName"), "-Please Select-", new { #class = "form-control" })
#Html.ValidationMessageFor(Model => Model.SendSMSModel.SenderId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(Model => Model.SendSMSModel.Numbers, new { #class = "form-control-label" })
<div class="input-group">
<span class="input-group-addon input_email">
<i class="fa fa-sort-numeric-asc text-primary"></i>
</span>
#Html.TextBoxFor(Model => Model.SendSMSModel.Numbers, new { #class = "form-control form-control-md" })
#Html.ValidationMessageFor(Model => Model.SendSMSModel.Numbers, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SendSMSModel.MessageText, new { #class = "form-control-label" })
<div class="input-group">
<span class="input-group-addon input_email">
<i class="fa fa-file-text text-primary"></i>
</span>
#Html.EditorFor(model => model.SendSMSModel.MessageText, new { htmlAttributes = new { #class = "form-control", #onkeyup = "javascript:ValidateCharactercount(this);", #rows = "10", #cols = "50" } })
#Html.ValidationMessageFor(model => model.SendSMSModel.MessageText, "", new { #class = "text-danger" })
</div>
<div id="divmessage" style="color: Red;">
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Send Now" class="btn btn-info" />
</div>
</div>
</div>
Controller:
`[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SendMessage(SMS_SignatureModel sms)
{
Inetlab.SMPP.SmppClient client = new Inetlab.SMPP.SmppClient();
client.Connect("***.**.***.**", ****);
if (client.Status == ConnectionStatus.Open)
{
client.SystemType = "****";
client.Bind("******", "******", ConnectionMode.Transmitter);
if (client.Status == ConnectionStatus.Bound)
{
IList<SubmitSmResp> respList = client.Submit(
SMS.ForSubmit()
.From(sms.SendSMSModel.SenderId)
.To(sms.SendSMSModel.Numbers)
.Text(sms.SendSMSModel.MessageText)
.DeliveryReceipt()
.Coding(DataCodings.Default)
);
if (respList.Count > 0 && respList[0].Status == CommandStatus.ESME_ROK)
{
Console.WriteLine("SMS has been sent");
foreach (SubmitSmResp resp in respList)
{
Console.WriteLine("MessageId: " + resp.MessageId);
}
}
client.UnBind();
}
client.Disconnect();
}
return RedirectToAction("SendMessage", "SendSMS");
}
`
Help would be appreciated.
#Html.DropDownListFor(model => model.SendSMSModel.SenderId, new SelectList(ViewBag.SenderNameList, "SenderId", "SenderName"), "-Please Select-", new { #class = "form-control" })

Passing a List of objects from Razor View to Controller only passes one item instead of the whole list

I want to pass a List of VoedingBindingModel to my controller by using an Editor Template, however I only receive the first entry of the List in the Controller, never all the entries.
The Controller:
public ActionResult Create()
{
ViewBag.fk_customVoedingId = new SelectList(customvoeding.GetAllCustomvoeding(), "customVoedingId", "customVoedingNaam");
ViewBag.fk_standaardVoedingId = new SelectList(standaardvoeding.GetAllStandaardvoeding(), "standaardVoedingId", "standaardVoedingNaam");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Datum,Tijd,VoedingCollection")]AgendaBindingModel agendaBindingModel)
{
//Do something
}
The Model:
public class AgendaBindingModel
{
[Required]
public List<VoedingBindingModel> VoedingCollection { get; set; }
//More properties
}
The View:
#using Website.Models
#model AgendaBindingModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>agenda</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Datum, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Datum, "{0:dd-MM-yyyy}", new { #class = "form-control-datepicker", placeholder = "DD-MM-YYYY", maxlength = "10" })
#Html.ValidationMessageFor(model => model.Datum, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tijd, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Tijd, "{0:hh:mm}", new { htmlAttributes = new { #class = "form-control-timepicker", placeholder = "hh:mm", maxlength = "5" } })
#Html.ValidationMessageFor(model => model.Tijd, "", new { #class = "text-danger" })
</div>
</div>
<div id="CreateVoedingDiv0">
#Html.EditorFor(x => x.VoedingCollection[0])
</div>
<div id="CreateVoedingDiv1"hidden>
#Html.EditorFor(x => x.VoedingCollection[1])
</div>
<div id="CreateVoedingDiv2"hidden>
#Html.EditorFor(x => x.VoedingCollection[2])
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input value="Add" class="btn btn-default" onclick="ShowVoeding()" /> <input value="Remove" class="btn btn-default" onclick="HideVoeding()" />
</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>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script>
var count = 1;
function ShowVoeding()
{
if (document.getElementById("CreateVoedingDiv" + count).hidden == true)
{
document.getElementById("CreateVoedingDiv" + count).hidden = false;
count++;
}
}
function HideVoeding()
{
count = count - 1;
if (document.getElementById("CreateVoedingDiv" + count).hidden == false) {
document.getElementById("CreateVoedingDiv" + count).hidden = true;
}
}
</script>
Partial class:
(customvoeding and standaardvoeding do the same thing, only customvoeding returns a collection of customvoeding and standaardvoeding returns a collection of standaardvoeding.
public partial class customvoeding
{
private static foodtrackerEntities1 db = new foodtrackerEntities1();
public static List<customvoeding> GetAllCustomvoeding()
{
db.Configuration.LazyLoadingEnabled = false;
return db.customvoeding.ToList();
}
}
You don't seem to be initializing the model and passing it to the view. In the action methods of your controller try adding:
var viewModel = new AgendaBindingModel();
viewModel.VoedingCollection = // TODO: Fill the list from your data source
return View(viewModel );
Try like this. I could not test, but if you like we can advance is this way:
To show all items:
<div id="group">
#for(int i = 0; i < AgendaBindingModel.VoedingCollection.Count; i++)
{
#Html.EditorFor(x => x.VoedingCollection[i])
}
To add new item:
<button onclick=newItem() >+</button>
</div>
<script>
function newItem(){
var div = document.createElement('div');
div.id = CreateNewItem;
div.innerHTML = '#Html.EditorFor(x => x.VoedingCollection[i])';
document.body.appendChild(div);
}
</script>
Your second and third html are broken.
<div id="CreateVoedingDiv2"hidden>
remove hidden
I found out what was preventing me from receiving more than one result:
You can NOT use #Html.EditorFor template for more than 1 value when you specify a template. It does not matter if you use different models or different templates, it just simply does not work.
To fix it, you have to use 'Html.BeginCollectionItem' library, which can be found here.

JQuery Validation message shows on page load

I have the following view:
#model GRCWebApp.ViewModels.NewClubInterestsViewModel
#{
ViewBag.Title = "Add Club Interests";
}
<div class="col-md-10 col-offset-md-1">
<h2 class ="text-success">Add Club Interests for #Html.DisplayFor(model => model.Name)</h2>
</div>
#using (Html.BeginForm("NewInterests", "Club", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="row">
<div class="col-md-8">
<div class="well bs-component">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(x => Model.ClubId)
<div class="form-group">
<div class="col-md-10 col-md-offset-1">
<h3>Tick the areas your club is interested/runs events in</h3>
</div>
</div>
<div class="col-md-offset-1">
#for (int i = 0; i < Model.ClubTypeInterests.Count(); i++)
{
<div>
#Html.HiddenFor(x => Model.ClubTypeInterests[i].InterestId)
#Html.CheckBoxFor(x => Model.ClubTypeInterests[i].selected)
#Html.LabelFor(x => Model.ClubTypeInterests[i].InterestName, Model.ClubTypeInterests[i].InterestName)
</div>
}
</div>
<div class="form-group">
<div class="row">
<div class="col-md-offset-1 col-md-12">
<input type="submit" name="Submit" value="Next" class="btn btn-success btn-lg" /> to setup Online membership
<input type="submit" name="Submit" value="Complete" class="btn btn-warning btn-sm" /> to just provide online event entries
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
#using (Html.BeginForm("AddInterest", "Club"))
{
#Html.AntiForgeryToken()
<hr />
<div class="row">
<div class="col-md-8">
<div class="well bs-component">
<div class="form-group">
<div class="col-md-12 col-md-offset-1">
<h3>Not listed? - Add extras here</h3>
</div>
</div>
#Html.HiddenFor(model => model.ClubTypeId)
#Html.HiddenFor(model => model.ClubId)
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-inline">
<div class="form-group">
<div class="row col-md-offset-1 col-md-11">
<div class="col-md-4">
#Html.LabelFor(model => model.InterestName, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.InterestName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.InterestName, "", new { #class = "text-danger" })
</div>
<div class="col-md-5">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
<input type="submit" value="Add" class="btn btn-info" style="margin-top: 22px" />
</div>
</div>
</div>
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Overtime the page loads the Validation message shows for InterestName in the second form AddInterest.
The Get method for the whole form is:
[HttpGet]
public ActionResult NewInterests(NewClubInterestsViewModel model, int id)
{
//Find the Club and then pass its id to the ViewModel
var club = db.Clubs.Find(id);
//model.ClubId = club.ClubId ;
//Interests List
IEnumerable<Interest> allExistingInterests;
//Generate a list of the interests that apply to that type of club
using (ApplicationDbContext context = new ApplicationDbContext())
{
allExistingInterests = context.Interests
.Where(s => s.ClubTypeId == club.ClubTypeId)
.OrderBy(s => s.InterestName)
.ToList();
}
IEnumerable<int> clubInterestIds = club.ClubInterests.Select(x => x.InterestId).ToList();
//Generate the ViewModel with the appropriate Interests
var viewModel = new NewClubInterestsViewModel
{
ClubId = club.ClubId,
Name = club.Name,
ClubTypeId = club.ClubTypeId,
ClubTypeInterests =
allExistingInterests.Select(
x => new ClubInterestsViewModel { InterestId = x.InterestId, InterestName = x.InterestName, selected = clubInterestIds.Contains(x.InterestId) }).ToArray()
};
return View(viewModel);
}
What do I need to do to stop the validation message showing on load?
Remove the NewClubInterestsViewModel model parameter from your GET method. It should be just
public ActionResult NewInterests(int id)
The first step in the model binding process is that instances of your parameters are initialized and then its properties are set based on form values, route values, query string values etc. In your case there are no values to set, so the properties of your model are their defaults, but because you have validation attributes on your properties, validation fails and errors are added to ModelState which are then displayed in the view.

Categories

Resources