EF Saving only the 1st child entity - asp.net-mvc

I'm trying to save an Event and EventDetails corresponding to that event.
It's saving the Event and the 1st EventDetail from the loop only.
public class Event
{
[Key]
public int CourseId { get; set; }
..
public virtual ICollection<EventDetail> EventDetails{ get; set; }
}
Controller:
[HttpPost]
public ActionResult Create(Event ev)
{
if (ModelState.IsValid)
{
IQueryable<EventDetail> eventList = ..;
FutureEvents fe = new FutureEvents();
ICollection<FutureEvents> feCol = new Collection<FutureEvents>();
foreach (EventDetail det in eventList)
{
fe.Name = ..;
db.Entry(fe).State = EntityState.Added;
feCol.Add(fe);
}
ev.EventDetails = feCol;
db.Event.Add(ev);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ev);
}

Move
FutureEvents fe = new FutureEvents();
within foreach loop. You created exactly one FutureEvents, so one is saved.

You have created a single object then modified it in every iteration. Try this out:
[HttpPost]
public ActionResult Create(Event ev)
{
if (ModelState.IsValid)
{
IQueryable<EventDetail> eventList = ..;
ICollection<FutureEvents> feCol = new Collection<FutureEvents>();
foreach (EventDetail det in eventList)
{
FutureEvents fe = new FutureEvents();
fe.Name = ..;
db.Entry(fe).State = EntityState.Added;
feCol.Add(fe);
}
ev.EventDetails = feCol;
db.Event.Add(ev);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ev);
}

Related

WCF---Consuming CRUD operation using Linq in ASP.NET MVC application?

enter image description here
First step...Opened WCF created IService:
namespace CRUDOperationWCFMVC
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
bool CreateDetails(EmployeeDetails employeeDetails);
[OperationContract]
bool UpdateDetails(EmployeeDetails employeeDetails);
[OperationContract]
bool DeleteDetails(int id);
[OperationContract]
List<EmployeeDetails> GetDetails();
}
public class EmployeeDetails
{
[DataMember]
public int EmpID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Location { get; set; }
[DataMember]
public int? Salary { get; set; }
}
}
Step 2: then I implemented service code:
public class Service1 : IService1
{
DataClasses1DataContext dcd = new DataClasses1DataContext();
public bool CreateDetails(EmployeeDetails employeeDetails)
{
Nevint emp = new Nevint();
emp.EmpID= employeeDetails.EmpID;
emp.Name = employeeDetails.Name;
emp.Location = employeeDetails.Location;
emp.Salary = employeeDetails.Salary;
dcd.Nevints.InsertOnSubmit(emp);
dcd.SubmitChanges();
return true;
}
public bool DeleteDetails(int id)
{
var delete = (from v in dcd.Nevints where v.EmpID==id select v).FirstOrDefault();
dcd.Nevints.DeleteOnSubmit(delete);
dcd.SubmitChanges();
return true;
}
public List<EmployeeDetails> GetDetails()
{
List<EmployeeDetails> details = new List<EmployeeDetails>();
var select= (from v in dcd.Nevints select v);
foreach (var i in select)
{
EmployeeDetails emp = new EmployeeDetails();
emp.EmpID = i.EmpID;
emp.Name = i.Name;
emp.Location = i.Location;
emp.Salary = i.Salary;
details.Add(emp);
}
return details;
}
public bool UpdateDetails(EmployeeDetails employeeDetails)
{
var update = (from v in dcd.Nevints.ToList() where employeeDetails.EmpID==v.EmpID select v).FirstOrDefault();
update.EmpID = employeeDetails.EmpID;
update.Name = employeeDetails.Name;
update.Location = employeeDetails.Location;
update.Salary = employeeDetails.Salary;
dcd.SubmitChanges();
return true;
}
}
Step 3: then I add linq to sql, opened my ASP.NET MVC project for consuming, and added a controller and wrote this code:
namespace ConsumingClient.Controllers
{
public class EmpdetailsController : Controller
{
ServiceReference1.Service1Client serobj=new ServiceReference1.Service1Client();
ServiceReference1.EmployeeDetails empdetails=new ServiceReference1.EmployeeDetails();
// GET: Empdetails
public ActionResult Index()
{
List<employee> lstemp = new List<employee>();
var result = serobj.GetDetails();
foreach (var i in result)
{
employee emp = new employee();
empdetails.EmpID = i.EmpID;
empdetails.Name = i.Name;
empdetails.Location = i.Location;
empdetails.Salary = i.Salary;
lstemp.Add(emp);
}
return View(result);
}
// GET: Empdetails/Details/5
public ActionResult Details(int id)
{
Employees emp = new Employees();
return View();
}
// GET: Empdetails/Create
public ActionResult Create()
{
return View();
}
// POST: Empdetails/Create
[HttpPost]
public ActionResult Create(Employees employees)
{
try
{
// TODO: Add insert logic here
empdetails.EmpID=employees.EmpID;
empdetails.Name = employees.Name;
empdetails.Location = employees.Location;
empdetails.Salary = employees.Salary;
serobj.CreateDetails(empdetails);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
// GET: Empdetails/Edit/5
public ActionResult Edit(int id)
{
Employees emp = new Employees();
var result = serobj.GetDetails().FirstOrDefault(a=>a.EmpID==id);
emp.EmpID = result.EmpID;
emp.Name = result.Name;
emp.Location = result.Location;
emp.Salary = result.Salary;
return View(emp);
}
// POST: Empdetails/Edit/5
[HttpPost]
public ActionResult Edit(Employees employees)
{
try
{
// TODO: Add update logic here
empdetails.EmpID = employees.EmpID;
empdetails.Name = employees.Name;
empdetails.Location = employees.Location;
empdetails.Salary = employees.Salary;
serobj.UpdateDetails(empdetails);
return RedirectToAction("Index");
}
catch
{
return View(employees);
}
}
// GET: Empdetails/Delete/5
public ActionResult Delete(int id)
{
Employees emp = new Employees();
var result = serobj.GetDetails().FirstOrDefault(a=>a.EmpID==id);
emp.EmpID = result.EmpID;
emp.Name = result.Name;
emp.Location = result.Location;
emp.Salary = result.Salary;
return View(emp);
}
// POST: Empdetails/Delete/5
[HttpPost]
public ActionResult Delete(int id, FormCollection collection)
{
try
{
// TODO: Add delete logic here
serobj.DeleteDetails(id);
return RedirectToAction("Index");
}
catch
{
return View(id);
}
}
}
}
Data was displaying fine. I can create data.
However, when I click on edit and delete, I'm getting an error:
ERROR Message "Server Error in '/' Application.
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32)' in 'ConsumingClient.Controllers.EmpdetailsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
This error is thrown if you attempt to call this controller action and you do not specify the id either in the path portion or as query string parameter. Since your controller action takes an id as parameter you should make sure that you always specify this parameter.
Make sure that when you are requesting this action you have specified a valid id in the url:
http://example.com/somecontroller/Edit/123
If you are generating an anchor, make sure there's an id:
#Html.ActionLink("Edit", "somecontroller", new { id = "123" })
If you are sending an AJAX request, also make sure that the id is present in the url.
If on the other hand the parameter is optional, you could make it a nullable integer:
public ActionResult Edit(int? id)
but in this case you will have to handle the case where the parameter value is not specified.
https://coderedirect.com/questions/197477/mvc-the-parameters-dictionary-contains-a-null-entry-for-parameter-k-of-non-n

Can't convert from int to "classname"

While building a ASP.NET-MVC website I was trying to implement a EDIT page on my website, but I'm having some difficulties, particulary in my Controller. The error is in this class, pointing to the ID:
public IActionResult Edit(int ID = 0)
{
GestaoAlertas _teste = addresses.Contains(ID);
return View(_teste);
}
And the error says:
It is not possible to convert from int to "hdsportal.GestaoAlertas"
Controller:
public class HomeController : Controller
{
SqlCommand com = new SqlCommand();
SqlDataReader dr;
SqlConnection con = new SqlConnection();
List<GestaoAlertas> addresses = new List<GestaoAlertas>();
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
con.ConnectionString = "secret";
}
public IActionResult Gestao_Alertas()
{
FetchData();
return View(addresses);
}
[Route("")]
public IActionResult Index()
{
FetchData();
return View(addresses);
}
public IActionResult Edit(int ID = 0)
{
GestaoAlertas _teste = addresses.Contains(ID);
return View(_teste);
}
public IActionResult Privacidade()
{
return View();
}
public IActionResult Gestao_Utilizadores()
{
return View();
}
public IActionResult Contatos()
{
return View();
}
public IActionResult QuemSomos()
{
return View();
}
private void FetchData()
{
if (addresses.Count > 0)
{
addresses.Clear();
}
try
{
con.Open();
com.Connection = con;
com.CommandText = "SELECT [ID], [SYSTEM_NAME], [SYSTEM_STATUS], [SYSTEM_SHORTMSG] FROM [CORE_SYS_STATUS]";
dr = com.ExecuteReader();
while (dr.Read())
{
addresses.Add(new GestaoAlertas()
{
ID = (int)dr["ID"]
,
SYSTEM_NAME = dr["SYSTEM_NAME"].ToString()
,
SYSTEM_STATUS = dr["SYSTEM_STATUS"].ToString()
,
SYSTEM_SHORTMSG = dr["SYSTEM_SHORTMSG"].ToString()
});
}
con.Close();
}
catch (Exception ex)
{
throw ex;
}
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
Model:
public class GestaoAlertas
{
public int ID { get; set; }
public string SYSTEM_NAME { get; set; }
public string SYSTEM_STATUS { get; set; }
public string SYSTEM_SHORTMSG { get; set; }
}
Issue & Concern
According to List<T>.Contains(T), you need parse T object which is GestaoAlertas object to your addresses (List<GestaoAlertas> type).
Hence, you get the error below as it is an unmatched type with int
It is not possible to convert from int to "hdsportal.GestaoAlertas"
for this line:
GestaoAlertas _teste = addresses.Contains(ID);
And List<T>.Contains(T) returns the boolean result.
public bool Contains (T item);
Determines whether an element is in the List.
Solution(s)
Assumptions:
addresses contain GestaoAlertas records
You can get GestaoAlertas element from addresses by ID with either of these LINQ methods:
Pre-requisite:
Import System.Linq namespace.
using System.Linq;
Solution 1: Enumerable.SingleOrDefault
Returns a single, specific element of a sequence, or a default value if that element is not found.
Note: It will throw InvalidOperationException if input sequence contains more than one element. Good to be use for unique identifier such as ID.
GestaoAlertas _teste = addresses.SingleOrDefault(x => x.ID == ID);
Solution 2: Enumerable.Single
Returns a single, specific element of a sequence.
Note: It will throw ArgumentNullException if it returns null.
GestaoAlertas _teste = addresses.Single(x => x.ID == ID);
Solution 3: Enumerable.FirstOrDefault
Returns the first element of a sequence, or a default value if no element is found.
GestaoAlertas _teste = addresses.FirstOrDefault(x => x.ID == ID);
Solution 4: Enumerable.First
Returns the first element of a sequence.
Note: It will throw ArgumentNullException if it returns null.
GestaoAlertas _teste = addresses.First(x => x.ID == ID);

How to Edit Two Model in one View EntityFramework.dll error

This my Code
Model
public class ViewModelRequestPurchaseItem
{
public List<RequestPurchase> RequestPurchases { get; set; }
public List<RequestPurchaseItem> RequestPurchaseItems { get; set; }
}
View
#using EFMySQLCardTest.Models
#model EFMySQLCardTest.Models.ViewModelRequestPurchaseItem
Controller
public ActionResult Edit([Bind(Include = "RequestPurchases,RequestPurchaseItems")] ViewModelRequestPurchaseItem viewModelRequestPurchaseItem, string id)
{
var requestPurchase = db.RequestPurchase.Where(x => x.RequestPurchaseNumber == id).ToList();
var requestPurchaseItem = db.RequestPurchaseItem.Where(x => x.RequestPurchaseNumber == id).OrderBy(x => x.RequestPurchaseItemID).ToList();
viewModelRequestPurchaseItem.RequestPurchases = requestPurchase;
viewModelRequestPurchaseItem.RequestPurchaseItems = requestPurchaseItem;
if (ModelState.IsValid)
{
db.Entry(viewModelRequestPurchaseItem).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
this.ExpendErrors();
}
return View(viewModelRequestPurchaseItem);
}
In this line:
db.Entry(viewModelRequestPurchaseItem).State = EntityState.Modified
the error is:
viewModelRequestPurchaseItem is not model of parts
ViewModelRequestPurchaseItem is your view model and is not part of the database context. You need to save each RequestPurchase and RequestPurchaseItems in the collections. You current code is also assigning the collections to the current values in the database, wiping out any edits you have made in the view. Your method should be
public ActionResult Edit(ViewModelRequestPurchaseItem model)
{
if (ModelState.IsValid)
{
return View(model);
}
foreach (RequestPurchase item in model.RequestPurchases)
{
db.Entry(item).State = EntityState.Modified;
}
// ditto for RequestPurchaseItems
db.SaveChanges();
return RedirectToAction("Index");
}

Telerik RadScheduler Datasource

I have the ff code:
// note: entries is a list binded to a query from the database
// wherein i'm passing some parameters to satisfy
// the conditions from the query
foreach (var entry in entries)
{
Appointment appointment = new Appointment();
appointment.Start = entry.StartDateTime;
appointment.End = entry.EndDateTime;
appointment.Summary = entry.Summary;
this.radScheduler.Appointments.Add(appointment);
}
Is there a way to bind the entries directly to radScheduler without using foreach statement?
I've also tried using radScheduler.datasource but it doesn't work.
Please check below code :
.aspx
<telerik:RadScheduler ID="RadScheduler1" runat="server" DataKeyField="ID" DataSubjectField="Subject"
DataStartField="StartDate" DataEndField="EndDate" >
.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<MyScedule> lst = new List<MyScedule>();
MyScedule obj = new MyScedule();
obj.ID = 1;
obj.Subject = "my Subject";
obj.StartDate = DateTime.Now;
obj.EndDate = DateTime.Now.AddHours(1);
lst.Add(obj);
MyScedule obj1 = new MyScedule();
obj1.ID = 2;
obj1.Subject = "my Subject";
obj1.StartDate = DateTime.Now.AddHours(2);
obj1.EndDate = DateTime.Now.AddHours(3);
lst.Add(obj1);
RadScheduler1.DataSource = lst;
RadScheduler1.DataBind();
}
}
.cs
public class MyScedule
{
public int ID { get; set; }
public string Subject { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
http://www.telerik.com/help/aspnet-ajax/scheduler-database-structure.html
It worked from my side.

Using ViewModels in asp.net mvc 3

Here is my scenario: (These all have to accomplished in the same view as an accepted requirement)
User enters a few search criterias to search users.
Page lists the search results with an update link besides.
User clicks on one of the update links and a form appears to enable editing the data.
User does changes and saves the data that binded to form.
I used a view model for this view. Here it is.
[Serializable]
public class UserAddModel
{
public UserSearchCriteria UserSearchCriteria { get; set; }
public UserEntity User { get; set; }
public List<UserPrincipalDto> SearchResults { get; set; }
}
And here is my controller:
using System;
namespace x.Web.BackOffice.Controllers
{
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
[Authorize(Roles = "Admin")]
public class UserController : Controller
{
private readonly IAuthentication _authentication;
private readonly List<RoleEntity> roles = new Y.Framework.Data.Repository<RoleEntity>().Get(null).ToList();
private Repository<UserEntity> repository = new Repository<UserEntity>();
[ImportingConstructor]
public UserController(IAuthentication authentication)
{
this._authentication = authentication;
}
public ActionResult Index()
{
return View(new UserAddModel());
}
[HttpPost]
public ActionResult GetSearchResults(UserAddModel model)
{
if (ModelState.IsValid)
{
try
{
List<UserPrincipalDto> results =
_authentication.SearchUsers(
ConfigurationManager.AppSettings["DomainName"],
model.UserSearchCriteria.FirstName,
model.UserSearchCriteria.LastName,
model.UserSearchCriteria.Username);
model.SearchResults = results;
Session["UserAddModel"] = model;
return View("Index", model);
}
catch (Exception ex)
{
Logger.Log(ex, User.Identity.Name);
}
}
else
{
ModelState.AddModelError("", "Error!");
}
Session["UserAddModel"] = model;
return View("Index", model);
}
public ActionResult Save(string username)
{
UserAddModel model = Session["UserAddModel"] as UserAddModel;
UserEntity exists = repository.Get(u => u.Username == username).FirstOrDefault();
if (exists == null)
{
UserPrincipal userPrincipal =
_authentication.GetUserDetails(
ConfigurationManager.AppSettings["DomainName"],
username);
model.User = new UserEntity();
model.User.Id = userPrincipal.Guid.Value;
model.User.FirstName = userPrincipal.DisplayName.FullNameToFirstName();
model.User.LastName = userPrincipal.DisplayName.FullNameToLastName();
model.User.Email = userPrincipal.EmailAddress;
model.User.Username = userPrincipal.SamAccountName;
}
else
{
model.User = new UserEntity();
model.User.Id = exists.Id;
model.User.FirstName = exists.FirstName;
model.User.LastName = exists.LastName;
model.User.Email = exists.Email;
model.User.Username = exists.Username;
model.User.RoleId = exists.RoleId;
}
ViewBag.Roles = roles;
return View("Index", model);
}
[HttpPost]
public ActionResult Save(UserAddModel model)
{
UserEntity exists = repository.Get(u => u.Id == model.User.Id).FirstOrDefault();
if (exists == null)
{
Result result = repository.Save(model.User);
HandleResult(result, model);
}
else
{
Result result = repository.Save(model.User, PageMode.Edit);
HandleResult(result, model);
}
ViewBag.Roles = roles;
return View("Index", model);
}
}
}
As you see there are two different forms in my view and I'm storing the whole view model in Session in my controller. But I think this is not fine enough. What if session expires or what if I have to deploy my application using a load balancer?
What is the best way to develop this kind of page? I'm open to any kind of suggestions.
Thanks in advance,

Resources