Bind data from database to DropDownListFor in asp.net mvc 2.0 - asp.net-mvc-2

I am a new in asp.net mvc 2.0, I tried to search about this article but still can not get the answer like what I want.
I have one form to assign the role to each employee. So I create one form that I can input the employee's name and select the role that they are in. The role are taking from table Role. I used linq to sql to query the RoleName and RoleID from table Role, and want to bind it to DropDownListFor in my view.
I have one model :
public class UserModels
{
public string name { get; set; }
public string role { get; set; }
}
This is what I did in my controller :
[HttpPost]
public ActionResult UserMaintenance(FormCollection frm)
{
if (ModelState.IsValid)
{
EMP_DBSEntities context = new EMP_DBSEntities();
tblUserLogin user = new tblUserLogin();
user.UserName = frm["userLogin"].ToString();
IEnumerable<SelectListItem> role_list = context.tblRoles.Select(d => new SelectListItem
{
Value = d.RoleID.ToString(),
Text = d.RoleName
});
context.AddTotblUserLogins(user);
context.SaveChanges();
return View();
}
else
{
return View();
}
}
Can anyone tell me how could I bind the role_list to my DropDownListFor<> in my view.
Thanks.

In order to create a drop down list you need a view model with 2 properties: a scalar property that will contain the selected value and a collection property that will contain the available options.
So as always in ASP.NET MVC start by writing a view model:
public class UserRoleViewModel
{
[DisplayName("name")]
public string EmployeeName { get; set; }
[DisplayName("role")]
public int? SelectedRoleId { get; set; }
public IEnumerable<SelectListItem> Roles { get; set; }
}
then a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
// fetch the roles
// could come from a database or something
var roles = new[]
{
new { RoleID = 1, RoleName = "Admin" },
new { RoleID = 2, RoleName = "Foo" },
new { RoleID = 3, RoleName = "Bar" },
new { RoleID = 4, RoleName = "Baz" },
};
// Now we build the model
var model = new UserRoleViewModel
{
EmployeeName = "John", // could come from a database or something
SelectedRoleId = 1, // could come from a database or something
Roles = new SelectList(roles, "RoleID", "RoleName")
};
return View(model);
}
[HttpPost]
public ActionResult Index(UserRoleViewModel model)
{
return Content(
string.Format(
"Selected role for {0} is {1}", model.EmployeeName, model.SelectedRoleId
)
);
}
}
and finally a view:
<%# Page
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<UserRoleViewModel>"
%>
...
<% using (Html.BeginForm()) { %>
<%= Html.EditorFor(x => x.EmployeeName) %>
<%= Html.DropDownListFor(x => x.SelectedRoleId, Model.Roles, "-- Role --") %>
<button type="submit">OK</button>
<% } %>

Related

Get query data to view

I'm new in ASP.NET Core 3.1 and I'm trying to pass query data (entity framework) to view.
This is my query
public void OnGet()
{
var query = (from panier in _context.panier
join product in _context.product on panier.id_product equals product.Id_Product
where panier.username == HttpContext.Session.GetString("username")
select new
{
product.nom_product,
product.Image,
panier.Qte,
panier.prix,
panier.Prix_total
});
query.ToList();
}
But I don't know how to call the result in VIEW
You should define a list in your PageModel. Below is a simple example:
IndexModel:
public List<User> Users { get; set; }
public void OnGet()
{
Users = new List<User>
{
new User{ Id = 1, Name = "A"},
new User{ Id = 2, Name = "B"},
new User{ Id = 3, Name = "C"},
};
}
And in the view:
#page
#model IndexModel
#{
ViewData["Title"] = "Home page";
}
#foreach (var u in Model.Users)
{
<label>#u.Name</label><br />
}

Retrieve course id and course name selected in edit view(get) when edit data

Image for what i need
i need when edit employee data show to me courses that submit before
this is my secnario
in create view
courses drowpdown user select three courses
Delphi
Flash
c++
then when click submit button for employee.it will have 3 courses submitted
I need to retrieve courses that submitted before for employee martin
from database
in edit view(get)
I need to show :
course name course id
Delphi 1
Flash 2
c++ 3
and CourseId will be hidden
what i write in edit view to show selected course
my code as below for view and controller
Edit.cs.html view
#model WebCourse.Models.Customemployee2
<body>
<div>
#using (Html.BeginForm())
{
<div>
Name:#Html.TextBoxFor(a => a.Name)
<br />
Courses:#Html.DropDownList("CourseId")
<table id="tb2"></table>
<br />
<input type="submit" />
</div>
}
</div>
</body>
in empcourse controller
namespace WebCourse.Controllers
{
public class empcourseController : Controller
{
mycourseEntities db = new mycourseEntities();
// GET: empcourse
public ActionResult Edit(int id)
{
Employee old = db.Employees.Find(id);
if (old != null)
{
var vm = new Customemployee2();
vm.Name = old.Name;
ViewBag.CourseId = new SelectList(db.Courses.ToList(), "Id", "CourseName");
return View(vm);
}
}
}
}
model view Customemployee2
namespace WebCourse.Models
{
public class Customemployee2
{
public string Name { get; set; }
public int CourseId { get; set; }
public List<EmployeeCourse> Courses { get; set; }
}
}
I suggest you update your edit view model to have a collection of CourseVm
public class EditEmployeeVm
{
public int Id { set; get; }
public string Name { get; set; }
public List<SelectListItem> Courses { get; set; }
public int[] CourseIds { set; get; }
public List<CourseVm> ExistingCourses { set; get; }
}
public class CourseVm
{
public int Id { set; get; }
public string Name { set; get; }
}
Now in your Edit GET action, populate the ExistingCourse collection.
public ActionResult Edit(int id)
{
var vm = new EditEmployeeVm { Id=id };
var emp = db.Employees.FirstOrDefault(f => f.Id == id);
vm.Name = emp.Name;
vm.ExistingCourses = db.EmployeeCourses
.Where(g=>g.EmployeeId==id)
.Select(f => new CourseVm { Id = f.CourseId,
Name = f.Course.Name}).ToList();
vm.CourseIds = vm.ExistingCourses.Select(g => g.Id).ToArray();
vm.Courses = db.Courses.Select(f => new SelectListItem {Value = f.Id.ToString(),
Text = f.Name}).ToList();
return View(vm);
}
Now in your Edit view, just loop through the ExistingCourses collection and display it.
#model EditEmployeeVm
#using (Html.BeginForm())
{
#Html.HiddenFor(g=>g.Id)
#Html.LabelFor(f=>f.Name)
#Html.DropDownList("AvailableCourses" ,Model.Courses,"Select")
<h4>Existing courses</h4>
<div id="items"></div>
foreach (var c in Model.ExistingCourses)
{
<div class="course-item">
#c.Name Remove
<input type="text" name="CourseIds" value="#c.Id" />
</div>
}
<input type="submit"/>
}
You should have the below javascript code also in the view to handle the remove and add of a course.
#section scripts
{
<script>
$(function() {
$(document).on("click",".remove",function(e) {
e.preventDefault();
$(this).closest(".course-item").remove();
});
$('#AvailableCourses').change(function() {
var val = $(this).val();
var text =$("#AvailableCourses option:selected").text();
var existingCourses = $("input[name='CourseIds']")
.map(function() { return this.value; }).get();
if (existingCourses.indexOf(val) === -1) {
// Not exist. Add new
var newItem = $("<div/>").addClass("course-item")
.append(text+' Remove ');
newItem.append('<input type="text" name="CourseIds"
value="' + val + '" />');
$("#items").append(newItem);
}
});
})
</script>
}
So when you submit the form, The CourseIds property will have the course ids (as an array).
[HttpPost]
public ActionResult Edit(EditEmployeeVm model)
{
// to do : check model.ExistingCourses and save the data now
}
BTW, The same can be used for your create form.

Bind data from database to dropdownlist using asp.net mvc 2.0

I have problem with the data that I select from table tblemployee that I want to bind it to the dropdownlist.
model
public class UserModels
{
public string EmployeeName { get; set; }
public int EmployeeCode { get; set; }
public IEnumerable<SelectListItem> Employee { set; get; }
}
Controller
public ActionResult Education() {
var query = (from e in context.tblEmployee_Employee
select new
{
empID = e.Code,
EmpName = e.NameEng
}
).ToList();
var model = new UserModels();
var _Emp = query;
foreach (var item in _Emp)
{
model.EmployeeCode = item.empID;
model.EmployeeName = item.EmpName;
model.Employee = new SelectList(_Emp, "EmpName", "EmpName");
}
return View(model);
}
View
<%= Html.DropDownListFor(x => x.EmployeeName, Model.Employee, "select EmployeeName")%>
And I got the error message "Object reference not set an instance of an object".Anyone know please kindly tell me how to solve it.
Thanks,
Try like this:
public ActionResult Education()
{
var model = new UserModels();
model.Employee = context
.tblEmployee_Employee
.ToList()
.Select(e => new SelectListItem
{
Value = e.Code.ToString(),
Text = e.NameEng
});
return View(model);
}
And make sure that your view is strongly typed to the UserModels view model and then:
<%= Html.DropDownListFor(
x => x.EmployeeName,
Model.Employee,
"select EmployeeName"
) %>

Cannot get relationship to update for navigation properties in entity framework

I am currently using EF4.3 and Code First. Creation of my objects works (via my views - just using the auto-generated Create), but when I attempt to edit an object, it does not save any changes that, utlimately, tie back to my navigation properties. I have been reading on relationships, but I don't understand how to tell my context that the relationship has changed.
Here is some example code of my implementation.
#* Snippet from my view where I link into my ViewModel. *#
<div class="row">
<div class="editor-label">
#Html.LabelFor(model => model.ManagerID)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.ManagerID, ViewBag.Manager as SelectList, String.Empty)
#Html.ValidationMessageFor(model => model.ManagerID)
</div>
</div>
Here is my Controller implementation (POST of my Edit):
[HttpPost]
public ActionResult Edit(ProjectViewModel projectViewModel)
{
if (ModelState.IsValid)
{
Project project = new Project();
project.ProjectID = projectViewModel.ProjectID;
project.Name = projectViewModel.Name;
project.ProjectManager = repository.GetUser(projectViewModel.ManagerID);
repository.InsertOrUpdateProject(project);
repository.Save();
return RedirectToAction("Index");
}
ViewBag.Manager = new SelectList(repository.GetUsers(), "UserID", "FullName", projectViewModel.ManagerID);
return View(projectViewModel);
}
Within my Project object:
public class Project
{
public int ProjectID { get; set; }
[Required]
public string Name { get; set; }
// Navigation Properties
public virtual User Manager { get; set; }
}
Here is the corresponding method from the repository (where my context resides):
public void InsertOrUpdateProject(Project project)
{
if (program.ProjectID == default(int))
{
context.Projects.Add(project);
}
else
{
context.Entry(project).State = EntityState.Modified;
}
}
Just to be clear, this does work to update my properties, but it does not update my navigation properties (in this case, Manager). Appreciate any help.
Setting the state to Modified only marks scalar properties as modified, not navigation properties. You have several options:
A hack (you won't like it)
//...
else
{
var manager = project.Manager;
project.Manager = null;
context.Entry(project).State = EntityState.Modified;
// the line before did attach the object to the context
// with project.Manager == null
project.Manager = manager;
// this "fakes" a change of the relationship, EF will detect this
// and update the relatonship
}
Reload the project from the database including (eager loading) the current manager. Then set the properties. Change tracking will detect a change of the manager again and write an UPDATE.
Expose a foreign key property for the Manager navigation property in your model:
public class Project
{
public int ProjectID { get; set; }
[Required]
public string Name { get; set; }
public int ManagerID { get; set; }
public virtual User Manager { get; set; }
}
Now ManagerID is a scalar property and setting the state to Modified will include this property. Moreover you don't need to load the Manager user from the database, you can just assign the ID you get from your view:
Project project = new Project();
project.ProjectID = projectViewModel.ProjectID;
project.Name = projectViewModel.Name;
project.ManagerID = projectViewModel.ManagerID;
repository.InsertOrUpdateProject(project);
repository.Save();
There are several options here, I will list 3 of them:
Option 1: Using GraphDiff
*This needs the Configuration.AutoDetectChangesEnabled of your context set to true.
Just install GraphDiff with NuGet
Install-Package RefactorThis.GraphDiff
Then
using (var context = new Context())
{
var customer = new Customer()
{
Id = 12503,
Name = "Jhon Doe",
City = new City() { Id = 8, Name = "abc" }
};
context.UpdateGraph(customer, map => map.AssociatedEntity(p => p.City));
context.Configuration.AutoDetectChangesEnabled = true;
context.SaveChanges();
}
For more details about GraphDiff look here.
Option 2: Find and Edit
Searching your entity with EF to track it to the context. Then edit the properties.
*This needs the Configuration.AutoDetectChangesEnabled of your context set to true.
var customer = new Customer()
{
Id = 12503,
Name = "Jhon Doe",
City = new City() { Id = 8, Name = "abc" }
};
using (var context = new Contexto())
{
var customerFromDatabase = context.Customers
.Include(x => x.City)
.FirstOrDefault(x => x.Id == customer.Id);
var cityFromDataBase = context.Cities.FirstOrDefault(x => x.Id == customer.City.Id);
customerFromDatabase.Name = customer.Name;
customerFromDatabase.City = cityFromDataBase;
context.Configuration.AutoDetectChangesEnabled = true;
context.SaveChanges();
}
Option 3: Using a scalar property
In a matter of performance this is the best way, but it mess your class with database concerns. Because you will need to create a scalar (primitive type) property to map the Id.
*In this way there is no need to set the Configuration.AutoDetectChangesEnabled to true. And also you won't need to do a query to the database to retrieve the entities (as the first two options would - yes GraphDiff does it behind the scenes!).
var customer = new Customer()
{
Id = 12503,
Name = "Jhon Doe",
City_Id = 8,
City = null
};
using (var contexto = new Contexto())
{
contexto.Entry(customer).State = EntityState.Modified;
contexto.SaveChanges();
}
I am not sure exactly what you mean by navigation properties? Do you mean like a foreign key relationship? If so then try the following data annotation:
public class Project
{
public int ProjectID { get; set; }
[Required]
public string Name { get; set; }
[ForeignKey("YourNavigationProperty")]
public virtual UserManager { get; set; }
}
Update your EF Context, and see what happens?
UPDATE
public class Project
{
public int ProjectID { get; set; }
[Required]
public string Name { get; set; }
[ForeignKey("ManagerId")]
public ManagerModel UserManager { get; set; }
}
public class ManagerModel
{
[Key]
public int ManagerId { get; set; }
public String ManagerName { get; set; }
}
See if that works?

default check in radiobutton list in MVC?

i am passing list of values in radiobutton ( 5 values). but i want one among them should be selected/checked by default. How can i do that?
You could set the view model property to the required value. Example:
public class MyViewModel
{
public string Value { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel { Value = "No" };
return View(model);
}
}
and in the view:
<%= Html.RadioButtonFor(x => x.Value, "Yes", new { id = "yes" }) %> Yes
<%= Html.RadioButtonFor(x => x.Value, "No", new { id = "no" }) %> No
<%= Html.RadioButtonFor(x => x.Value, "Maybe", new { id = "maybe" }) %> Maybe
which will select the No button.