I want to display a checkbox in view using razor syntax.
the model property IsActive should be int.
Model is:-
public class Student
{
public int StudentID { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public int IsActive { get; set; }
}
View is:-
<div class="editor-label">
#Html.LabelFor(model => model.IsActive)
</div>
<div class="editor-field">
#Html.CheckBoxFor(model => model.IsActive)
#Html.ValidationMessageFor(model => model.IsActive)
</div>
I should display checkbox and if checkbox is checked,1 should be saved to the database and if umchecked 0 should be saved.
Pls help me...
Thanks..
What don't you understand in the error message ? You can't use CheckBoxFor for an int property.
You should change your model and set
public bool IsActive {get;set;}
Now, there's probably a good reason for it to be an int, but hard to say why with your code...
if IsActive can be only 0 or 1, you should use a ViewModel class, and use a boolean property, which you will map to your class.
public class StudentViewModel
{
public int StudentID { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public bool IsActive { get; set; }
}
then when you get your student from your db (in your "GET" action")
something like that (rustic)
public ActionResult StudentEdit(int id) {
var student = getStudentById(id);
var model = new StudentViewModel {
StudentId = student.StudentID,
Code = student.Code,
Description = student.Description,
IsActive = student.IsActive == 1
};
return View(model);
}
Your view should be typed with StudentViewModel
#model StudentViewModel
then in your POST action, reverse
[HttpPost]
public ActionResult StudentEdit(StudentViewModel model) {
var student = getStudentById(model.StudentID);
student.Code = model.Code;
student.Description = model.Description;
student.IsActive = model.IsActive ? 1 : 0;
UpdateStudent(student);
return Redirect...
}
EDIT :
This is a really rustic answer, and I'm sure you could do better.
For that, we would need some more infos :
Are you using Entity Framework (version) ?
If yes, Code first, Database first, model first ?
Which database is behind ?
Can you change something to the database ?
What type has IsActive in database ?
IsActive should be a bool, #Html.CheckBoxFor() helper method expects boolean parameter
change code to
public bool IsActive { get; set; }
Related
I'm new to MVC, and stuck on what should be a pretty straight forward issue. I'm working through this tutorial and got everything pretty much working, except I now want to add a foreign key 'link' (not sure what it's called) but can't seem to get it to work. Here's what I have:
Tables:
Inventory:
Id | SerialNumber | ManufacturerId (foreignkey to Manufactueres->id)
Manufactureres
Id (primary key) | Name
Model (InventoryItem.cs):
public class InventoryItem {
public int Id {get; set; }
public int SerialNumber{ get; set; }
//this starts the trouble, I actually want to interact with the Manufactureres table -> Name column
public int ManufacturerId { get; set; }
}
View (Create.cshtml):
...
//What i really want is a dropdown of the values in the Manufactureres table
#Html.EditorFor(model=> model.ManufacturerId)
This must be a farely common issue when using a relational database there would be many foreign key relationships to be used/shown, but for some reason i can't find a tutorial or issue on stackoverflow that directly corresponds to something so simple. Any guidance, or direction is much appreciated!
Thanks,
I hope I understand your question correctly. Seems like when you want to add a new inventory item then you want a list of all the manufacturers in a dropdown list. I am going to work on this assumption, please let me know if I am off the track :)
Firstly go and create a view model. This view model you will bind to yout view. Never bind domain objects to your view.
public class InventoryItemViewModel
{
public int SerialNumber { get; set; }
public int ManufacturerId { get; set; }
public IEnumerable<Manufacturer> Manufacturers { get; set; }
}
Your domain objects:
public class InventoryItem
{
public int Id { get; set; }
public int SerialNumber{ get; set; }
public int ManufacturerId { get; set; }
}
public class Manufacturer
{
public int Id { get; set; }
public string Name { get; set; }
}
Your controller might look like this:
public class InventoryItemController : Controller
{
private readonly IManufacturerRepository manufacturerRepository;
private readonly IInventoryItemRepository inventoryItemRepository;
public InventoryItem(IManufacturerRepository manufacturerRepository, IManufacturerRepository manufacturerRepository)
{
// Check that manufacturerRepository and inventoryItem are not null
this.manufacturerRepository = manufacturerRepository;
this.inventoryItemRepository = inventoryItemRepository;
}
public ActionResult Create()
{
InventoryItemViewModel viewModel = new InventoryItemViewModel
{
Manufacturers = manufacturerRepository.GetAll()
};
return View(viewModel);
}
[HttpPost]
public ActionResult Create(InventoryItemViewModel viewModel)
{
// Check that viewModel is not null
if (!ModelState.IsValid)
{
Manufacturers = manufacturerRepository.GetAll()
return View(viewModel);
}
// All validation is cool
// Use a mapping tool like AutoMapper
// to map between view model and domain model
InventoryItem inventoryItem = Mapper.Map<InventoryItem>(viewModel);
inventoryItemRepository.Insert(inventoryItem);
// Return to which ever view you need to display
return View("List");
}
}
And then in your view you might have the following:
#model MyProject.DomainModel.ViewModels.InventoryItems.InventoryItemViewModel
<table>
<tr>
<td class="edit-label">Serial Number <span class="required">**</span></td>
<td>#Html.TextBoxFor(x => x.SerialNumber, new { maxlength = "10" })
#Html.ValidationMessageFor(x => x.SerialNumber)
</td>
</tr>
<tr>
<td class="edit-label">Manufacturer <span class="required">**</span></td>
<td>
#Html.DropDownListFor(
x => x.ManufacturerId,
new SelectList(Model.Manufacturers, "Id", "Name", Model.ManufacturerId),
"-- Select --"
)
#Html.ValidationMessageFor(x => x.ManufacturerId)
</td>
</tr>
</table>
I hope this helps :)
Yes, this is common issue, you need select Manufactureres in action and then send them to view. You can use ViewBag or strontly typed view model.
Examples:
Problem populating dropdown boxes in an ASP.NET MVC 3
Application
Having difficulty using an ASP.NET MVC ViewBag and
DropDownListfor
MVC3 Razor #Html.DropDownListFor
This is what I would recommend you.
1) Create a Manufacturer model class
public class Manufacturer
{
public int Id { get; set; }
public string Name { get; set; }
}
2) Create InventoryItem model class as follows
public class InventoryItem
{
public int Id { get; set; }
public int SerialNumber{ get; set; }
public int ManufacturerId { get; set; }
[ForeignKey("Id ")]
public Manufacturer Manufacturer{get; set;}
public IEnumerable<Manufacturer> Manufacturer {get;set;}
}
3) Make sure DbContext is also updated as follows
public DbSet<InventoryItem> InventoryItem {get;set;}
public DbSet<Manufacturer> Manufacturer{get;set;}
4) Controller
[HttpGet]
public ActionResult Create()
{
InventoryItem model = new InventoryItem();
using (ApplicationDbContext db = new ApplicationDbContext())
{
model.Manufacturer= new SelectList(db.Manufacturer.ToList(), "Id", "Name");
}
return View(model);
}
[HttpPost]
public ActionResult Create(InventoryItem model)
{
//Check the Model State
if(! ModelState.IsValid)
{
using (ApplicationDbContext db = new ApplicationDbContext())
{
model.Manufacturer= new SelectList(db.Manufacturer.ToList(), "Id", "Name");
return View(model);
}
}
using (ApplicationDbContext db = new ApplicationDbContext())
{
InventoryItem dto = new InventoryItem();
dto.SerialNumber= model.SerialNumber;
dto.Id= model.Id;
Manufacturer manudto = db.Manufacturer.FirstOrDefault(x => x.Id== model.Id);
dto.CatName = manudto.CatName;
db.Test.Add(dto);
db.SaveChanges();
}
TempData["SM"] = "Added";
return RedirectToAction("Index");
}
5) Make sure View has dropdownselect option in below format
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Id, Model.Manufacturer,"Select", new { #class = "form-control" } )
#Html.ValidationMessageFor(model => model.Id, "", new { #class = "text-danger" })
</div>
</div>
Hope this works :D
I am trying to create an Item that has an ItemType coming from another table. I am unable to get back the actual Type object from the Create page. This is the code I have tried:
Models:
public class ItemType {
public int Id { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<Item> Item{ get; set; }
}
public class Item {
public int Id { get; set; }
[Required]
public string Name { get; set; }
public virtual ItemType ItemType { get; set; }
}
In the ItemController, this is my create code:
public ActionResult Create() {
var itemTypeRepo = new ItemTypeRepository(context);
ViewBag.ItemTypes = new SelectList(itemTypeRepo.GetAll(), "ID", "Name");
return View();
}
[HttpPost]
public ActionResult Create(Item item) {
if (ModelState.IsValid) {
context.Items.Add(item);
context.SaveChanges();
return RedirectToAction("Index");
}
return View(item);
}
In my Create.cshtml view I have tried:
<div class="editor-field">
#Html.DropDownList("ItemType", String.Empty)
#Html.ValidationMessageFor(model => model.ItemType)
</div>
This returns no value at all and throws an error "The value 'X' is invalid." Where X is the ID of the ItemType I selected.
And
<div class="editor-field">
#Html.DropDownListFor(x => x.ItemType.Id, (SelectList)ViewBag.ItemType)
#Html.ValidationMessageFor(model => model.ItemType)
</div>
This creates a stub ItemType object with the correct ID but does not insert it into the database since the object is not fully loaded. If I look at ModelState object, I find that there is an error that the Name field is missing from ItemType object.
I also attempted to solve the problem using the second .cshtml code and adding this code:
public ActionResult Create(Item item) {
item.ItemType = context.ItemTypes.Find(item.ItemType.Id);
if (ModelState.IsValid)
This does not change the value of ModelState.IsValid from false even through it should.
What do I need to do to get this to work?
You should add a property ItemTypeId to your Item entity so that it acts as a foreign key.
public class Item
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public int ItemTypeId { get; set; }
[ForeignKey("ItemTypeId")]
public virtual ItemType ItemType { get; set; }
}
You can then use that property for the dropdownlist:
<div class="editor-field">
#Html.DropDownListFor(x => x.ItemTypeId, (SelectList)ViewBag.ItemType)
#Html.ValidationMessageFor(model => model.ItemType)
</div>
How make a dropdownlist? [Edited - almost working code]
View:
<div class="editor-label">
Firma
<div class="editor-field">
#Html.DropDownListFor(x => x.ID_firma, Model.firmaList)
#Html.ValidationMessageFor(model => model.nazwa)
</div>
Model:
public class produktModel
{
[Required(ErrorMessage="Proszę podać nazwę.")]
public string nazwa { get; set; }
[Required(ErrorMessage = "Proszę podać ilść produktu.")]
public decimal ilosc { get; set; }
[Required(ErrorMessage = "Proszę podać jednostkę produktu (np. kg, l, szt.).")]
public string jednostka { get; set; }
[Required(ErrorMessage = "Proszę podać cenę produktu.")]
public decimal cena { get; set; }
public string ID_firma { get; set; }
public IEnumerable<SelectListItem> firmaList { get; set; }
}
Controller:
public ActionResult dodaj()
{
var firma = baza.Firmas;
var model = new produktModel
{
firmaList = firma.AsEnumerable().Select(x => new SelectListItem
{
Value = x.ID_firma.ToString(),
Text = x.nazwa
})
};
return View(model);
}
[HttpPost]
public ActionResult dodaj(produktModel model)
{
Produkt prod = new Produkt();
prod.nazwa = model.nazwa;
prod.ilosc = model.ilosc;
prod.jednostka = model.jednostka;
prod.cena = model.cena;
prod.ID_firma = model.ID_firma;
baza.Produkts.InsertOnSubmit(prod);
baza.SubmitChanges();
return RedirectToAction("zarzadzaj_produktami", "Produkt");
}
It almost work...
I have only one problem (I hope)...
Value is string, and I save his value to database... (I don't now how to write it...)
prod.ID_firma = model.ID_firma;
prod.ID_firma is int. model.ID_firma is this value which is string. So I have an error:
Error 1 Cannot implicitly convert type 'string' to 'int?'
change your model a bit, i have assumed the column names change them according to your code
public class produktModel
{
[Required]
public string name { get; set; }
public decimal price { get; set; }
[Required]
public int companyID {get; set;}
public List<Company> compList {get; set;}
}
public class Company{
public int CompanyID {get;set;}
public string CompanyName {get;set;}
}
ActionResult should look like
public ActionResult add()
{
produktModel model = new produktModel();
model.compList= (from b in base.Companies
select new Company{
CompanyID = b.CompanyID,
CompanyName = b.CompanyName
}).ToList();
return View(model);
}
in your (strongly typed) view
#model produktModel
....
<div class="editor-label">
Company
<div class="editor-field">
#Html.DropDownListFor(model => model.companyID,
new SelectListItem(model.compList,
"CompanyID ",
"CompanyName "))
#Html.ValidationMessageFor(model => model.company_name)
</div>
...
Your question isn't clear enough.
Any way you can use the telerik combox\dropdown list or the default mvc dropdown list. you can find a lot of examples on google for that.
With Telerik write something like this:
#(Html.Telerik().ComboBox()
.Name("ComboBox")
.BindTo(new SelectList("CompanyID", "CompanyName")))
see this Telerik demo for more information.
I hope someone can help with this one. I have three Model classes like this:
public class Provider
{
public Guid ProviderId { get; set; }
public string Name { get; set; }
public Guid LocationId { get; set; }
public virtual Location Location { get; set; }
}
public class Location
{
public Guid LocationId { get; set; }
public string NameOrCode { get; set; }
public string Description { get; set; }
public string StreetNumber { get; set; }
public string StreetAddress1 { get; set; }
public string StreetAddress2 { get; set; }
public string City { get; set; }
public int? StateId { get; set; }
public string Zip { get; set; }
public string ContactPhone { get; set; }
public virtual State State { get; set; }
}
public class State
{
public int StateId { get; set; }
public string Name { get; set; }
public string Abbreviation { get; set; }
}
As you can see, a Provider has a Location (separate class for reuse elsewhere), and a Location has a State (which is null until selected).
My Controller looks like this for my Create methods:
public class ProviderController : BaseController
{
private SetupContext db = new SetupContext();
// other CRUD methods ...
//
// GET: /Provider/Create
public ActionResult Create()
{
Location location = new Location()
{
LocationId = Guid.NewGuid(),
NameOrCode = Resources.BillingLocation,
Description = Resources.BillingLocationDescription
};
Provider provider = new Provider()
{
ProviderId = Guid.NewGuid(),
LocationId = location.LocationId,
Location = location
};
ViewBag.StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
return View(provider);
}
//
// POST: /Provider/Create
[HttpPost]
public ActionResult Create(Provider provider)
{
if (ModelState.IsValid)
{
db.Locations.Add(provider.Location);
db.Providers.Add(provider);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
return View(provider);
}
// other CRUD methods ...
}
Finally, my View looks like this:
<div class="editor-label">
#Html.LabelFor(model => model.Location.StateId, #Resources.Location_State_Display_Name)
</div>
<div class="editor-field">
#Html.DropDownList("StateId", #Resources.ChooseFromSelectPrompt)
#Html.ValidationMessageFor(model => model.Location.StateId)
</div>
My problem is that the state the user selects in the DropDownList never gets set on my Model on the Create POST. I have similar code in my Edit View and the state is populated correctly in that View (that is, the state associated with an existing Provider.Location shows selected in the DropDownList for the user to edit if desire), but in both the Create and the Edit Views the selection made by the user is never registered in my Model (specifically the Provider.Location.StateId) coming in from the POST.
Looking at the HTML produced I see this:
<div class="editor-label">
<label for="Location_StateId">State/Territory</label>
</div>
<div class="editor-field">
<select id="StateId" name="StateId"><option value="">[Choose]</option>
<option value="1">Alabama</option>
<option value="2">Alaska</option>
<!-- more options ... -->
</select>
<span class="field-validation-valid" data-valmsg-for="Location.StateId" data-valmsg-replace="true"></span>
</div>
I suspect I need to somehow convey the Location.StateId relationship instead of just StateId as I see above but I can't figure out the correct syntax to do that. I've tried changing my ViewBag dynamic property to Location_StateId like this:
ViewBag.Location_StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
And the DropDownList in my View like this:
#Html.DropDownList("Location_StateId", #Resources.ChooseFromSelectPrompt)
I figured then perhaps that notation would work because the label beside my DropDownList was rendered as:
<div class="editor-label">
<label for="Location_StateId">State/Territory</label>
</div>
This attempt did not work. Can you help me out?
Thanks in advance.
#Html.DropDownList("Location.StateId", #Resources.ChooseFromSelectPrompt)
Also the following line doesn't do anything useful:
ViewBag.StateId = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
You are assigning a SelectList to something that is supposed to be a scalar property. You probably wanted to pass the collection as ViewBag:
ViewBag.States = new SelectList(db.States, "StateId", "Name", provider.Location.StateId);
and then in the view:
#Html.DropDownList("Location.StateId", (SelectList)ViewBag.States)
I'm trying (without success) to use the Remote validator on a DropDownList:
// Person.cs
public int PersonID { get; set; }
public string Name { get; set; }
// Card.cs
public int CardID { get; set; }
[Remote("PersonValidation", "Validation", ErrorMessage = "...")]
public int PersonID { get; set; }
public virtual Person Person { get; set; }
// CardController
public ActionResult Create()
{
ViewBag.PersonID = new SelectList(db.Persons, "PersonID", "Name");
Card card = new Card();
return View(card);
}
// create.cshtml (Card Views)
<div class="editor-label">#Html.LabelFor(model => model.personID, "Person")</div>
<div class="editor-field">
#Html.DropDownList("PersonID", String.Empty)
#Html.ValidationMessageFor(model => model.PersonID)
</div>
// ValidationController.cs
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public JsonResult PersonValidation(int id)
{
Person person = db.Persons.Find(id);
return Json(person.Cards.Count > 0, JsonRequestBehavior.AllowGet);
}
The PersonValidation is never fired. The others "Remote" validations with text input are working perfectly.
Am I doing something wrong or is there a problem with DropDownList Remote validation?
Thanks!
The validator does not fire because you need to use #Html.DropDownListFor() in order to create an HTML element with "data-val" elements, which will be parsed into unobtrusive validators.