How to pass data from index view to edit view - asp.net-mvc-4

when click edit link in index page
it give me error
The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies.Employee_2EF71CC17A29BA91B02BC5CDB0EE5AF82D363EEF7E174A21C9546772913AA929', but this dictionary requires a model item of type 'WebCourse.Models.Customemployee'.
I have custom model Customemployee
namespace WebCourse.Models Customemployee
{
public class Customemployee
{
//represent employee table in database
public string Name { get; set; }
public int Salary { get; set; }
public string Email { get; set; }
public int DistrictId { get; set; }
//represent employee course table in database
public List<EmployeeCourse> Courses { get; set; }
//represent employee language table in database
public List<EmployeeLangage> Langs { get; set; }
}
}
and my controller empcourse
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebCourse.Models;
using System.Data.Entity;
namespace WebCourse.Controllers
{
public class empcourseController : Controller
{
mycourseEntities db = new mycourseEntities();
// GET: empcourse
public ActionResult Index()
{
var query = db.Employees.ToList().Select(p => new EmpInfo
{
Id = p.Id,
Name = p.Name,
Salary = Convert.ToInt32( p.Salary),
Email = p.Email,
DistrictName = p.Destrict.DistrictName,
CityName = p.Destrict.City.CityName,
CountryName = p.Destrict.City.Country.CountryName,
CourseNames = p.EmployeeCourses.Select(t => t.Course.CourseName).ToList(),
LanguageName = p.EmployeeLangages.Select(t => t.Language.LnaguageName).ToList(),
levelName = p.EmployeeLangages.Select(t => t.Level.LevelName).ToList(),
CourseName = string.Join(",", p.EmployeeCourses.Select(t => t.Course.CourseName).ToList())
});
return View(query);
}
public ActionResult Create()
{
ViewBag.CountryId = new SelectList(db.Countries, "Id", "CountryName");
ViewBag.LanaguageId = new SelectList(db.Languages.ToList(), "Id", "LnaguageName");
ViewBag.LevelId = new SelectList(db.Levels.ToList(), "Id", "LevelName");
ViewBag.CourseId = new SelectList(db.Courses.ToList(), "Id", "CourseName");
return View();
}
public ActionResult Edit(int id)
{
//how to pass data from index view to edit view
Employee old = db.Employees.Find(id);
return View(old);
}
[HttpPost]
public ActionResult Create(Customemployee cemp)
{
using (mycourseEntities db = new mycourseEntities())
{
Employee E = new Employee { Name = cemp.Name, Salary = cemp.Salary, Email = cemp.Email, DistrictId = cemp.DistrictId };
foreach (var i in cemp.Courses)
{
E.EmployeeCourses.Add(i);
db.SaveChanges();
}
foreach (var i in cemp.Langs)
{
E.EmployeeLangages.Add(i);
db.SaveChanges();
}
db.Employees.Add(E);
db.SaveChanges();
}
return View();
}
public JsonResult getcitybyid(int id)
{
db.Configuration.ProxyCreationEnabled = false;
return Json(db.Cities.Where(a => a.CountryId == id), JsonRequestBehavior.AllowGet);
}
public JsonResult getdistrictbyid(int id)
{
db.Configuration.ProxyCreationEnabled = false;
return Json(db.Destricts.Where(a => a.CityId == id), JsonRequestBehavior.AllowGet);
}
}
}
the error show here in code
public ActionResult Edit(int id)
{
//how to pass data from index view to edit view
Employee old = db.Employees.Find(id);
return View(old);
}
How to pass data from index view that show data to edit view

From the error message, it looks like your Edit view is strontly typed to Customemployee type. That means you should be passing an object of Customemployee class from your Edit action method to this view. But your current code is sending an object of Employee type.
So update your Edit action method to send the correct object to the view.
public ActionResult Edit(int id)
{
Employee old = db.Employees.Find(id);
if(old!=null)
{
var vm = new CustomEmployee();
vm.Name = old.Name;
vm.Email = old.Email;
// Assign other property values as needed.
return View(vm);
}
return Content("No employees found for the Id passed");
// to do : Ideally return a "NotFound" view
}

Related

OptGroup in SelectListItem Not showing in DropDownList

I wrote a method to show Items and in Groups in DropDownlist with SelectListItem, But the problem is that only show the first group name and child plus the childs of other groups. The problem is that do not show second, third,.. groups (but show their childs).
My model is
public class PermissionsViewModel
{
public long ID { get; set; }
public string Title { get; set; }
public long TypeId { get; set; }
public long? ParentId { get; set; }
public string ParentTitle { get; set; }
public List<PermissionsViewModel> ParentList { get; set; }
public List<PermissionsViewModel> OperationsList { get; set; }
public List<PermissionTypesDto> PermissionTypesList { get; set; }
public bool Status { get; set; }
}
Method to retrieve data:
public Dictionary<long?,List<PermissionsViewModel>> GetPermissionsByModule()
{
var ItemValue = (_ipermissionTypes.Expose().FirstOrDefault(x => x.Title == "Operation").Id);
var permissionbymodule = _ntumcontext.Tbl_Permissions
.Where(x => x.Status == true && x.TypeId == ItemValue)
.Select(x => new PermissionsViewModel
{
ID = x.ID,
Title = x.Title,
Status = x.Status,
ParentId = x.ParentId,
ParentTitle=x.permission.Title,
TypeId=x.TypeId,
}).AsEnumerable().GroupBy(x => x.ParentId).ToList();
return permissionbymodule.ToDictionary(k => k.Key, v => v.ToList());
}
And the Method to get on razor page (View):
public List<SelectListItem> Permissions = new List<SelectListItem>();
public List<SelectListItem> GetPermissionsByModule()
{
var AllPermissions = _ipermissionsApplication.GetPermissionsByModule();
foreach (var (key, value) in AllPermissions)
{
var parentTitle = _ipermissionsApplication.GetDetails(key).Title; //get group title from key
var group = new SelectListGroup() { Name = parentTitle };
foreach (var per in value)
{
var item = new SelectListItem(per.Title, per.ID.ToString())
{
Group = group
};
Permissions.Add(item);
}
}
return Permissions;
}
And in cshtml :
<select asp-for="RoleVM.SelectedPermissions" asp-items="Model.Permissions">
At present with the above codes, the problem is that do not show the second and third and ... , only show the first group name, but show all child items of all groups.
Firstly,you need to check the value of AllPermissions,maybe the parentID is not exists,and then you need to check var parentTitle = _ipermissionsApplication.GetDetails(key).Title;maybe the second and third and.. parentTitle is null.
Here is a working demo(I use fake data):
public class TestPermissionsModel : PageModel
{
public List<SelectListItem> Permissions = new List<SelectListItem>();
public void GetPermissionsByModule()
{
var AllPermissions = new Dictionary<long, List<PermissionsViewModel>>()
{
{1,new List<PermissionsViewModel>{ new PermissionsViewModel{ ID=11,Title="title11", ParentId=1}, new PermissionsViewModel { ID = 12, Title = "title12", ParentId = 1 } } },
{2,new List<PermissionsViewModel>{ new PermissionsViewModel{ ID=21,Title="title21", ParentId=2}, new PermissionsViewModel { ID = 22, Title = "title22", ParentId = 2 } } },
{3,new List<PermissionsViewModel>{ new PermissionsViewModel{ ID=31,Title="title31", ParentId=3}, new PermissionsViewModel { ID = 32, Title = "title32", ParentId = 3 } } }
};
foreach (var (key, value) in AllPermissions)
{
var parentTitle = "parentTitle" + key; //get group title from key
var group = new SelectListGroup() { Name = parentTitle };
foreach (var per in value)
{
var item = new SelectListItem(per.Title, per.ID.ToString())
{
Group = group
};
Permissions.Add(item);
}
}
}
public void OnGet()
{
GetPermissionsByModule();
}
}
View:
<select asp-items="Model.Permissions"></select>
result:

Retrieve values from SQL database - EF

I'm trying to figure out how to pull values from a SQL database and display this in a razor view.
I have the following class using Entity Framework (I believe)
public class EventLog
{
[Key]
public int Id { get; set; }
public int EventId { get; set; }
public int MaxDelegates { get; set; }
public string Code { get; set; }
public DateTime End { get; set; }
public string Title { get; set; }
}
And I want to map title to DBTitle in the following model:
public class CourseDetailVM : CourseDetailSummaryVM
{
public EventLog DBTitle { get; set; }
}
I then want to see this in the following view:
#using TSW.Web.Helpers
#model TSW.Web.ViewModels.CourseDetailVM
#{
Layout = "~/Views/_Master.cshtml";
}
#Model.DBTitle.Title;
I have the following controller already in place (sorry for the length I plan to reduce this down):
public class CourseDetailController : BaseRenderController<CourseDetailPageDT>
{
private readonly ISitePageFactory _pageFactory = null;
private readonly IEventService _eventService = null;
public CourseDetailController(IEventService eventService, ISitePageFactory pageFactory)
{
_pageFactory = pageFactory;
_eventService = eventService;
}
public async Task<ActionResult> CourseDetail()
{
var homepage = _pageFactory.GetCurrentHomepage();
var model = Mapper.Map<CourseDetailVM>(CurrentContent);
model.Email = homepage.ContactEmail;
model.PhoneNumber = homepage.HeaderPhoneNumber;
model.InnerPageHeader.ShowHeading = true;
model.InnerPageHeader.Title = model.PageTitle;
if (model.Categories.Count == 1)
{
var categoryTagId = model.Categories.First().Id;
var contentTypeAlias = DocumentTypeHelper.GetDocumentTypeAlias<CourseListingPageDT>();
var courseCategoryPage = Umbraco.TypedContentAtXPath($"//{contentTypeAlias}")
.FirstOrDefault(x => x.GetPropertyValue<int>(Constants.DocumentTypes.CourseListingPage.Category) == categoryTagId);
if (courseCategoryPage != null)
{
model.InnerPageHeader.BackLink = Mapper.Map<LinkItem>(courseCategoryPage.Id);
}
}
try
{
model.Events = await _eventService.GetEventsForCourse(CurrentContent.AdministrateId);
}
catch (Exception ex)
{
model.Events = new StaticPagedList<Event>(Enumerable.Empty<Event>(), 1, 1, 0);
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
if (CurrentContent.Graphic != 0)
{
model.InnerPageHeader.Graphic = Mapper.Map<CtaItem>(CurrentContent.Graphic);
}
return View(model);
}
}
I've tried every suggestion I can google to add the mapping in the controlling but can't get my head around this simple function of pulling the value from a SQL database into the razor view.
Could anyone help me out?

Update data in multiple table relation(employee and employeecourse tables)

I have two tables employee and employee course in a one-to-many relation.
Needs: update name in table employee and courseid in employeecourse table in edit view
Problem: when click submit button in edit view it delete all data and save only selected
Courses from drop down courses just now
If no changes happen to courses by(add or remove courses) when click submit
Button it delete all
code logic
I try to using logic to delete all data when click submit then save all data
after changes
meaning submit button do two task
delete courses exist before for the employee i edit view
add the courses after all changes done in edit view for this employee
see image below
code
model class EditEmployeeVm
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; }
}
in edit function get i pass data to edit view
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.Id,
Name = f.Course.CourseName
}).ToList();
vm.CourseIds = vm.ExistingCourses.Select(g => g.Id).ToArray();
vm.Courses = db.Courses.Select(f => new SelectListItem
{
Value = f.Id.ToString(),
Text = f.CourseName
}).ToList();
return View(vm);
}
[HttpPost]
public ActionResult Edit(EditEmployeeVm model)
{
**//i need to save name employee changes in employee table and all courses changes in emloyeecourse table
//what is wrong here**
var emp = db.Employees
.Include(e => e.EmployeeCourses)
.FirstOrDefault(f => f.Id == model.Id);
foreach (var eec in emp.EmployeeCourses.ToList())
{
db.EmployeeCourses.Remove(eec);
}
foreach (var couseid in model.CourseIds)
{
db.EmployeeCourses.Add(new EmployeeCourse { CourseId = couseid, EmployeeId = emp.Id });
}
db.SaveChanges();
return View();
}
update
public ActionResult Edit(EditEmployeeVm model)
{
var emp = db.Employees.FirstOrDefault(f => f.Id == model.Id);
foreach (var couseid in model.CourseIds)
{
db.EmployeeCourses.Add(new EmployeeCourse { CourseId = couseid, EmployeeId = emp.Id });
db.SaveChanges();
}
return View();
}
I Try in code above under update section
i can add data and save when click submit button
but problem when click remove button to course by jquery
it remove it but it not save changes of remove in database
so that when open edit view again i see item i removed before
how to solve that when click submit button to save item removed in database

MVC4 Drop-down dynamic SelectList. what went wrong?

I am new to mvc4 and trying to generate dropdownlist dynamically. I want to create a list for next 10 years. Where my understanding gone wrong?
Model
using System.Web.Mvc;
using DropDownList.Models;
namespace DropDownList.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ddlist DropList = new ddlist();
var years = Enumerable.Range(DateTime.Now.Year, 10);
var select = new SelectList(years.Select(y => new SelectListItem()
{
Text = y.ToString(),
Value = y.ToString()
}));
DropList.CountryList = select.ToList();
return View(DropList);
}
}
}
----------Controller-----
using System.Text;
using System.Web.Mvc;
namespace DropDownList.Models
{
public class ddlist
{
[Required(ErrorMessage = "Please select a Country")]
public string CountryCode { get; set; }
public IEnumerable<SelectListItem> CountryList
{
get;
set;
}
}
}
-------------View-----------------
#model DropDownList.Models.ddlist
#{
Layout = null;
}
#Html.DropDownListFor(
model => model.CountryCode,
Model.CountryList, "select"
)
#Html.ValidationMessageFor(model => model.CountryCode
Following are the output. what i am expecting to see years like 2014, 2015..
select
System.Web.Mvc.SelectListItem
System.Web.Mvc.SelectListItem
System.Web.Mvc.SelectListItem
System.Web.Mvc.SelectListItem
System.Web.Mvc.SelectListItem
System.Web.Mvc.SelectListItem
System.Web.Mvc.SelectListItem
System.Web.Mvc.SelectListItem
System.Web.Mvc.SelectListItem
System.Web.Mvc.SelectListItem
It's more likely to return a SelectList
1) Change the model to:
public class ddlist
{
[Required(ErrorMessage = "Please select a Country")]
public string CountryCode { get; set; }
public SelectList CountryList
{
get;
set;
}
}
2) And then return the list as SelectList to the model:
public ActionResult Index()
{
DropList ddlist = new ddlist();
var years = Enumerable.Range(DateTime.Now.Year, 10);
var select = new SelectList(years.Select(y => new SelectListItem()
{
Text = y.ToString(),
Value = y.ToString()
}));
DropList.CountryList = select; //Removing the ToList and Using the SelectList
return View(DropList);
}

How to pass a complex model to an ActionAsPDF?

I am creating an MVC 4 application. I am using Rotativa to generate pdfs
they have a method called
public ActionAsPdf(string action, object routeValues);
I am having trouble passing in a complex object to the routeValues
i.e:
I have a viewModel
public class FullName
{
public string FirstName { get; set; }
public string Surname { get; set; }
}
public ActionResult Index(FullName name)
{
ViewBag.Message = string.Format("Hello {0} to ASP.NET MVC!", name);
return View();
}
public ActionResult Test()
{
var fullname = new FullName();
fullname.FirstName = "John";
fullname.Surname = "Smith";
return new ActionAsPdf("Index", new { name = fullname }) { FileName = "Test.pdf" };
}
when I step through, in the Index action the name is null... how do I pass the complex model through?
Check this
return new ActionAsPdf("Index", fullname ) { FileName = "Test.pdf" };
public ActionResult viewForPDFFile(int id)
{
Data data = new Manager().GetData(id);
return View(data); // this view content will show in PDF File
}
then call it simply
return new ActionAsPdf("viewForPDFFile", new { id = id} ) { FileName = String.Format("File_{0}.pdf",id) };