How to Implement CheckBoxFor in ASP.NET MVC 5? - c#

I'm trying to understand how to use CheckBoxFor in MVC 5. I'm new to MVC and trying to learn how Entity Framework works using code first migrations.
Here are my main class Request:
[KeyAttribute] //One solution said to add this. Made no difference.
public virtual Guid ID { get; set; }
[Required(ErrorMessage = "First Name is required.")] [Display(Name = "First Name:")] [StringLength(25, ErrorMessage = "First Name must not exceed 25 characters.")]
public virtual string FName { get; set; }
[Display(Name = "Middle Initial:")] [StringLength(1, ErrorMessage = "Middle Initial must not exceed 1 character.")]
public virtual string MI { get; set; }
[Required(ErrorMessage = "Last Name is required.")] [Display(Name = "Last Name:")] [StringLength(25, ErrorMessage = "Last Name must not exceed 25 characters.")]
public virtual string LName { get; set; }
[Required(ErrorMessage = "Date of Birth is required.")] [Display(Name = "Date of Birth:")]
public virtual DateTime DOB { get; set; }
[Required(ErrorMessage = "Email is required.")] [Display(Name = "Email:")] [StringLength(25, ErrorMessage = "Email must not exceed 50 characters.")]
public virtual string Email { get; set; }
[Required(ErrorMessage = "Phone Number is required.")] [Display(Name = "Phone Number")] [StringLength(14, ErrorMessage = "Phone number must not exceed 14 characters.")]
public virtual string Phone { get; set; }
[Required(ErrorMessage = "Phone Type selection is required.")] [Display(Name = "Phone Type:")] [StringLength(4, ErrorMessage = "Phone Type selection must not exceed 4 characters.")]
public virtual string PhoneType { get; set; }
[Required(ErrorMessage = "Preferred Contact Method selection is required.")] [Display(Name = "Preferred Contact Method:")] [StringLength(16, ErrorMessage = "Preferred Contact Method selection must not exceed 16 characters.")]
public virtual PrefContactViewModel PrefContactViewModel {get;set;}
[Display(Name = "Preferred Contact Time:")] [StringLength(50, ErrorMessage = "Preferred Contact Time must not exceed 50 characters.")]
public virtual string PrefContactTime { get; set; }
...
Here is my ViewModel PrefContactViewModel:
public int ID { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
Here is my controller RequestsController Index Action:
public ActionResult Index()
{
var requests = db.Requests.Include(r => r.PrefContactViewModel);
return View(requests.ToList());
}
Here is the same controller RequestForm Action:
public ActionResult RequestForm()
{
return View();
}
And here is my View:
#model AMYA.Models.Request
<div class="opensans margin-sides">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(false, "", new { #class = "text-danger" })
<hr />
//FIRST NAME, MIDDLE INITIAL, LAST NAME
<div>
<div class="form-group col-md-5">
#Html.LabelFor(model => model.FName, htmlAttributes: new { #class = "control-label" })<span class="red">*</span>
<div>
#Html.EditorFor(model => model.FName, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group col-md-2">
#Html.LabelFor(model => model.MI, htmlAttributes: new { #class = "control-label" })
<div>
#Html.EditorFor(model => model.MI, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group col-md-5">
#Html.LabelFor(model => model.LName, htmlAttributes: new { #class = "control-label" })<span class="red">*</span>
<div>
#Html.EditorFor(model => model.LName, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
//DATE OF BIRTH, EMAIL, PHONE NUMBER, PHONE TYPE
<div>
<div class="form-group col-md-3">
#Html.LabelFor(model => model.DOB, htmlAttributes: new { #class = "control-label" })<span class="red">*</span>
<div class="">
#Html.EditorFor(model => model.DOB, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group col-md-4">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label" })<span class="red">*</span>
<div class="">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group col-md-3">
#Html.LabelFor(model => model.Phone, htmlAttributes: new { #class = "control-label" })<span class="red">*</span>
<div class="">
#Html.EditorFor(model => model.Phone, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group col-md-2">
#Html.LabelFor(model => model.PhoneType, htmlAttributes: new { #class = "control-label" })<span class="red">*</span>
<div class="">
#Html.CheckBoxFor(model => model.PrefContactViewModel.Checked, new { #class = "form-control" })
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<div class="">
<input type="checkbox" id="PrefContact" name="PrefContact" value="#Request["PrefContact"]" />
#*#Html.EditorFor(model => model.PrefContact, new { htmlAttributes = new { #class = "checkbox" } })*#
#Html.CheckBoxFor(model => model.PrefContactViewModel.Checked, new { #class = "form-control" })
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
#Html.LabelFor(model => model.PrefContactTime, htmlAttributes: new { #class = "control-label" })
<div class="">
#Html.EditorFor(model => model.PrefContactTime, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
...
I just need to create a checkbox for each of the Name fields in my RequestForm Action. I've tried several of the solutions found here and elsewhere, but I cannot get the CheckBoxFor to work.
Can anyone offer me some insight into how to get CheckBoxFor to populate with the four selections? Or is there a way to do this using regular HTML <input> field?
And I get the following in my View:

(Update: I wrote this answer before I realised that the OP was using the List<> where each list item is its own field (i.e. as runtime customizable form builder) instead of representing each form field as a view-model class property, and this answer is not entire suitable for that scenario - but using EditorFor rather than CheckBoxFor should still work in this case).
You can't use an IEnumerable<T> as the static-type for a View's #model because ASP.NET model-binding (when repopulating the Model from the POST request body) works with List<T>, not IEnumerable<T>.
To use model-binding with a List<T> you need to use a for( int i = 0; i < list.Count; i++ )-style loop, you cannot use a foreach-style loop because it doesn't expose the item's index for use with the List<T>'s indexer property (okay, you can technically use foreach with .Select( (e, idx) => ... ) but it only results in more unproductive keyboard typing.
Change your ViewModel to its own class rather than directly exposing a List<T> anyway, because it makes everything else easier (such as adding a page title or other non-list content to the page).
Use a for() loop to render each item.
Your #model line must match the actual model object passed into View(Object).
Like so:
Controller action:
public class MyViewModel
{
// this is an example of an additional non-list-item property you'd add to the viewmodel:
[BindNever] // this is a one-way (server-to-client) property, so use [BindNever]
public String PageTitle { get; internal set; }
[Required]
public List<PrefContactViewModel> MyList { get; set; }
}
public ActionResult RequestForm()
{
MyViewModel vm = new MyViewModel()
{
PageTitle = "My list page!",
MyList = new List<PrefContactViewModel>
{
new PrefContactViewModel { ID = 1, Name = "Call", Checked = false },
new PrefContactViewModel { ID = 2, Name = "Text", Checked = false },
new PrefContactViewModel { ID = 3, Name = "Email", Checked = false },
new PrefContactViewModel { ID = 4, Name = "Traditional Mail", Checked = false },
}
};
return View( vm );
}
Your view:
#model MyViewModel
<div class="opensans margin-sides">
#using (Html.BeginForm()) {
<h1>#this.Model.PageTitle</h1>
#Html.AntiForgeryToken()
#Html.ValidationSummary(false, "", new { #class = "text-danger" })
<hr />
#for( int i = 0; i < this.Model.MyList.Count; i++ ) {
<!-- HTML markup removed for readability -->
#Html.LabelFor( m => m.MyList[i].FName )
#Html.TextBoxFor( m => m.MyList[i].FName )
#Html.ValidationMessageFor( m => m.MyList[i].FName )
#** Checkboxes should be wrapped in a <label> rather than using a separate label so you can't use #LabelFor **#
<label>#Html.CheckBoxFor( m => m.MyList[i].Checked ) #Html.DisplayNameFor( m => m.MyList[i].Checked )</label>
#Html.ValidationMessageFor( m => m.MyList[i].Checked )
#** etc for other members of each list item **#
} #** for loop **#
} #** </form> **#

Related

How to update table properties from related table in ASP.NET MVC

I've recently started with ASP.NET and I must say that I like it a lot. But in every relationship, you must hit some obstacle here and there. Here is mine:
My starting project includes creating simple schools system for managing students. I have several tables (Students, StudentAddresses, Grades, and Courses).
Here are problematic two tables:
1) Student table:
public Student()
{
this.Courses = new HashSet<Course>();
}
public int StudentId { get; set; }
[Required]
[StringLength(50, MinimumLength = 2, ErrorMessage = "The name must have over 2 and under 50 characters!")] // stavlja ograničenje na duljinu stringa u bazi
public string Name { get; set; }
[Required]
[StringLength(50, MinimumLength = 2, ErrorMessage = "The name must have over 2 and under 50 characters!")]
public string Surname { get; set; }
public int CurrentGradeId { get; set; }
public Grade CurrentGrade { get; set; }
public virtual StudentAdress Address { get; set; }
public virtual ICollection<Course> Courses { get; set; }
2) StudentAddress table:
public int StudentId { get; set; }
public string Address1 { get; set; }
public string Adress2 { get; set; }
public string City { get; set; }
public int ZipCode { get; set; }
public string Country { get; set; }
public virtual Student Student { get; set; }
In short, I'm trying to update StudentAddresses properties (to be more precise Address1 property for Student) while inside Student edit Action Method.
Here is View for Edit student:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Student</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.StudentId)
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Surname, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Surname, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Surname, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CurrentGradeId, "CurrentGradeId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("CurrentGradeId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CurrentGradeId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address.Address1, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address.Address1, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Address.Address1, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
And finally here is Edit Action Method for StudentsController:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "StudentId,Name,Surname,CurrentGradeId")] Student student )
{
if (ModelState.IsValid)
{
// getting student id for current studentid
StudentAdress addresa = db.Addresses.Find(student.StudentId);
// trying to bind input value
addresa.Address1 = student.Address.Address1.ToString();
// saving new value in StudentAddresses field Address1
db.Entry(addresa).State = EntityState.Modified;
db.SaveChanges();
db.Entry(student).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CurrentGradeId = new SelectList(db.Grades, "GradeId", "GradeName", student.CurrentGradeId);
return View(student);
}
So, in Edit method, I want to save new input value for Address1 inside Edit method for Student table. Or to put it simpler, I want to update field Address1 in StudentAddress class while Editing Student class
UPDATE 1
So, let's say that I've figure it out but I'm still wondering if it is proper and right way of doing it.
In Student Edit action method I added addresa.Address1 = Request.Form["Address.Address1"]; where I updated field with attribute name=Address.Address1 and it did a trick but I'm wondering if it is right way of doing it?
Keep in mind that I've tried this
**addresa.Address1 = student.Address.Address1;**
but using this "cleaner" approach gave me:
System.NullReferenceException: Object reference not set to an instance
of an object.
Could I updated Address.Address1 field using some other approach?
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "StudentId,Name,Surname,CurrentGradeId")] Student student )
{
if (ModelState.IsValid)
{
StudentAdress addresa = db.Addresses.Find(student.StudentId);
// newly added line
addresa.Address1 = Request.Form["Address.Address1"];
db.Entry(addresa).State = EntityState.Modified;
db.SaveChanges();
db.Entry(student).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CurrentGradeId = new SelectList(db.Grades, "GradeId", "GradeName", student.CurrentGradeId);
return View(student);
}
Your relationships are wrong.
In your StudentAddress model we can see the StudentId foreign key which means relationship between Student and StudentAddress is one to many. But in your Student model you have virtual StudentAdress Address which should be ICollection<StudentAdress> Addresses.
And in your add/edit you could just do:
var student = context.Student.Find(1);
student.Addresses.Add(new StudentAdress {
Address1 = "Ul. Janka Leskovara",
City = "Pregrada",
ZipCode = 49218,
Country = "Hrvatska"
});
context.SaveChanges();

Not saving to after Edit action

I am trying to save changes to in a basic CRUD. I have edited my view for 3 columns in my model (table has 7 columns).
I tried attach method which was referenced in a different post which did not work. Any thoughts would be appreciated.
Model
public class AssetRequest
{
public int Id { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Request date")]
public DateTime AssetRequestDate { get; set; }
[Display(Name = "Facility")]
public int FacilityId { get; set; }
[Required]
[Display(Name = "Asset requested")]
public int AssetId { get; set; }
[Display(Name ="Serial no.")]
public string AssetSN { get; set; }
[Required]
[Display(Name = "Request type")]
public int RequestTypeId { get; set; }
[Required]
[DataType(DataType.Date)]
[Display(Name = "Job date")]
public DateTime JobRequestDate { get; set; }
[Required]
[Display(Name = "Request status")]
public int RequestStatusId { get; set; }
[Display(Name = "Tracking no.")]
public string TrackingNo { get; set; }
[Display(Name = "Comments")]
public string Comments { get; set; }
[Display(Name = "Sending facility")]
public string SendingFacilityt { get; set; }
public virtual Asset Asset { get; set; }
public virtual Facility Facility { get; set; }
public virtual ApplicationUser User { get; set; }
public virtual RequestType RequestType { get; set; }
public virtual RequestStatus RequestStatus { get; set; }
}
}
Controller
public async Task<ActionResult> Edit([Bind(Include = "RequestStatusId, TrackingNo, Comments")] AssetRequest assetRequest)
{
if (ModelState.IsValid)
{
//db.AssetRequestTable.Attach(assetRequest);
db.Entry(assetRequest).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("All");
}
}
View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>AssetRequest</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.DistrictId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("DistrictId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.DistrictId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AssetId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("AssetId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.AssetId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RequestStatusId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("RequestStatusId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.RequestStatusId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TrackingNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TrackingNo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TrackingNo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comments, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Comments, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "All")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
You ned to include the Id property (which is the primary key) to the Include list so that EF can get the item and update it.
public async Task<ActionResult> Edit([Bind(Include = "Id,RequestStatusId, TrackingNo,
Comments")] AssetRequest assetRequest)
{
// your code
}
Looks like you are using your entity model as the parameter to update the entity values. A better approach to prevent over posting is to use a view model.

DropDownListFor Required validation only fires if optionLabel selected when another required field validation fires

I have a page with 2 textboxes and 2 dropdown lists.
The dropdown lists have optionLabels on them and I want the required validation to show if these are selected.
One of the textboxes and both of the dropdown lists are 'Required'.
If I complete the required textbox and submit the form, the 'Required' validation on the dropdown lists doesn't fire, it only fires if the 'Required' textbox doesn't have a value.
MODELS
public class CreateCaseModel
{
public CaseRegModel CaseDetails { get; set; }
public List<StartTypeListModel> CaseStartTypeList { get; set; }
public List<ClientListModel> ClientsList { get; set; }
}
public class CaseRegModel
{
[Key]
public int CaseId { get; set; }
[Required]
[Display(Name = "PX Request Date")]
public DateTime PxRequestDate { get; set; }
[Required]
public int ClientId { get; set; }
[Required]
[Display(Name = "Start Type")]
public string StartType { get; set; }
[Display(Name = "List Price")]
public string ListPrice { get; set; }
}
public class ClientListModel
{
[Required]
public int ClientId { get; set; }
[Display(Name = "Client Name")]
public string ClientName { get; set; }
}
public class StartTypeListModel
{
public int Id { get; set; }
[Required]
[Display(Name = "Start Type")]
public string StartType { get; set; }
}
VIEW - CreateCaseModel
<div class="form-group">
#Html.LabelFor(model => model.CaseDetails.StartType, new { #class = "control-label col-md-4" })
<div class="col-md-6">
#*#Html.DropDownList("StartType", null, "Select Start Type...", new { #class = "form-control" })*#
#Html.DropDownListFor(model => model.CaseDetails.StartType, new SelectList(Model.CaseStartTypeList, "StartType", "StartType"), "Select Start Type...", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CaseDetails.StartType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CaseDetails.PxRequestDate, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.CaseDetails.PxRequestDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CaseDetails.PxRequestDate, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
#Html.LabelFor(model => model.CaseDetails.ClientId, new { #class = "control-label col-md-4" })
<div class="col-md-6">
#*#Html.DropDownList("ClientId", null, "Select Client...", new { #class = "form-control" })*#
#Html.DropDownListFor(model => model.CaseDetails.ClientId, new SelectList(Model.ClientsList, "ClientId", "ClientName"), "Select Client...", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CaseDetails.ClientId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CaseDetails.ListPrice, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.CaseDetails.ListPrice, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CaseDetails.ListPrice, "", new { #class = "text-danger" })
</div>
</div>
CONTROLLER
// GET: Case/Create
public ActionResult Index()
{
//start type list
//var CategoryList = new List<string>();
var qStartTypes = (from st in efContext.CaseStartTypes
orderby st.Id
select new StartTypeListModel
{
Id = st.Id,
StartType = st.StartType
}).ToList();
//client list
//var CategoryList = new List<string>();
var qClients = (from c in efContext.PgsClients
orderby c.ClientName
select new ClientListModel
{
ClientId = c.ClientId,
ClientName = c.ClientName
}).ToList();
return View(new CreateCaseModel
{
CaseDetails = new CaseRegModel(),
CaseStartTypeList = qStartTypes,
ClientsList = qClients
});
}
Thanks for any help.

dependency validation based on dropdown selecion in MVC4

I have a dropdropdown list have values Yes, No. If you select yes I have validate next two textboxes. How can I do dependency validation based on dropdown selection?
public class MeetingAbstract
{
public string HasMaterialPublishedElseWhereLabel { get; set; }
public string HasMaterialPublishedElseWhereOptions { get; set; }
[Required]
public string HasMaterialPublishedElseWhereText { get; set; }
public string DtPublishedTimeId { get; set; }
public string DtPublishedTimeLabel { get; set; }
//validate this based on HasMaterialPublishedElseWhereText =Yes value
public string DtPublishedTimeText { get; set; }
public string PublishedPlaceId { get; set; }
public string PublishedPlaceLabel { get; set; }
//validate this based on HasMaterialPublishedElseWhereText =Yes value
public string PublishedPlaceText { get; set; }
}
view
<div class="row" style="padding-bottom: 10px">
<div class="col-md-10">
<div class="col-md-6">#Html.Label(Model.HasMaterialPublishedElseWhereLabel,
new {#class = "control-label mandatory"})</div>
<div class="col-md-4">
#{
options = Model.HasMaterialPublishedElseWhereOptions;
optionsList = options.Split(',').ToList();
optionSelect = optionsList.Select(option => new SelectListItem()
{Text = option, Value = option}).ToList();
}
#Html.DropDownListFor(model => model.HasMaterialPublishedElseWhereText,
optionSelect, i18n_Models_Abstract.SelectOption, new { #class = "input-
validation-error form-control" })
#Html.ValidationMessageFor(model => model.HasMaterialPublishedElseWhereText,
i18n_Models_Abstract.RequiredField,
new { style = "padding-left: 5px" })
</div>
</div>
</div>
<div class="row" style="padding-bottom: 10px">
<div class="col-md-10">
<div class="col-md-6">#Html.Label(Model.DtPublishedTimeLabel, new {#class =
"control-label mandatory"})</div>
<div class="col-md-4">#Html.TextBoxFor(model => model.DtPublishedTimeText, new \
{#class = "form-control", #placeholder = Model.DtPublishedTimeLabel,
required = "required", maxlength = 40})
#Html.ValidationMessageFor(model => model.DtPublishedTimeText,
i18n_Models_Abstract.RequiredField, new { style = "padding-left: 5px" })</div>
</div>
</div>
<div class="row" style="padding-bottom: 10px">
<div class="col-md-10">
<div class="col-md-6">#Html.Label(Model.PublishedPlaceLabel, new {#class =
"control-label mandatory"})</div>
<div class="col-md-4">#Html.TextBoxFor(model => model.PublishedPlaceText, new
{#class = "form-control", #placeholder = Model.PublishedPlaceLabel,
required = "required", maxlength = 40})
#Html.ValidationMessageFor(model => model.PublishedPlaceText,
i18n_Models_Abstract.RequiredField, new { style = "padding-left: 5px" })
</div>
</div>
</div>
I would add a Validate method on your model which will be called and exposed via ModelState.IsValid:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (this.HasMaterialPublishedElseWhereText == "Yes") {
yield return new ValidationResult("This isn't valid! Let me tell you why...");
}
}
Then in your controller simply call:
if (ModelState.IsValid) {
//You can only get this far if your Validate method
//doesn't return any ValidationResult objects.
//Do your magic!
}
Obviously this won't be executed client-side so if validation on the client is a requirement then you might need to roll that in.
One last note is that if you only have two values (e.g. Yes and No) a radio button may make more sense than a drop down.

MVC 5 Razor - Label isn't updated from class annotation

I have a simple example.
Two class. User and Company like :
public class User() {
public int UserID { get; set; }
[Display(Name = "User name")]
public string Name { get; set; }
[Display(Name = "Company")]
public int CompanyID { get; set; }
public virtual Company Company { get; set; }
}
public class Company() {
public int CompanyID { get; set; }
[Display(Name = "Company")]
public string Name { get; set; }
public virtual ICollection<User> Users { get; set; }
}
My problem is in the Create and the Edit views of the User.
The label for "Name" is displayed correctly in "User name" but the label for "CompanyID" stay displayed at "CompanyID" (the drop down list is created correctly with all Companies). I want the label display "Company" like I make it in the class.
I've try to change my view but all I do block compilation so I'm lost.
I'm begginer in MVC so excuse me if it easy to do but I don't see it.
Edit (add Create View code) :
#model Intranet3.Models.User
#{
ViewBag.Title = "Add a user";
}
#using (Html.BeginForm(null, null, FormMethod.Post, htmlAttributes: new { #class = "form-horizontal form-bordered" })) {
#Html.AntiForgeryToken()
<div class="row-fluid">
<div class="span12">
<div class="box">
<div class="box-title">
<h3>
<i class="icon-table"></i>
New
</h3>
</div>
<div class="box-content nopadding">
<div class="form-horizontal">
#Html.MyValidationSummary()
<div class="control-group #Html.ClassErrorFor(model => model.Name)">
#Html.LabelFor(model => model.Name, new { #class = "control-label" })
<div class="controls">
#Html.EditorFor(model => model.Name)
#Html.MyValidationMessageFor(model => model.Name)
</div>
</div>
<div class="control-group #Html.ClassErrorFor(model => model.CompanyID)">
#Html.LabelFor(model => model.CompanyID, "CompanyID", new { #class = "control-label" })
<div class="controls">
#Html.DropDownList("CompanyID", String.Empty)
#Html.MyValidationMessageFor(model => model.CompanyID)
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Create</button>
<button onclick="location.href='#Url.Action("Index","User")'" type="button" class="btn">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
}
Edit 2 :
Problem solved by delete the string force in Labels.
So this :
#Html.LabelFor(model => model.CompanyID, "CompanyID", new { #class = "control-label" })
Need to be
#Html.LabelFor(model => model.CompanyID, new { #class = "control-label" })
Why have u passed parameter CompanyId
#Html.LabelFor(model => model.CompanyID, "CompanyID", new { #class = "control-label" })
Should be
#Html.LabelFor(model => model.CompanyID, new { #class = "control-label" })
#Html.TextBoxFor(c => c.CompanyID, new { data_bind = "text:Contacts.FirstName", #class = "form-control" })
If you have knockoutjs binding

Categories