How to save the selected value from dropdownlist to database using Entity Framework in ASP.NET MVC 4 - entity-framework

In my one of the view I add a dropdown and I bind this drop down with my database like this..
public ActionResult PostMarks()
{
JoinMod std = new JoinMod();
std.Drp_bind = (from nm in db.TbStudent
select new SelectListItem
{
Text = nm.StudentName,
Value = SqlFunctions.StringConvert((double)nm.StudentId).Trim()
}).ToList<SelectListItem>();
return View(std);
}
Here is the dropdownlist in my view
<p>StudentName</p>
#Html.DropDownList("StudentName",Model.Drp_bind,"Select")
And on Post I am trying to save the data into the database like this
[HttpPost]
public ActionResult PostMarks(Marks marks)
{
db.TbMarks.Add(marks);
db.SaveChanges();
return RedirectToAction("ShowAllMarks");
}
Now when I check my database after save data in database the Id save in the database is zero from the dropdownlist. Please experts help me to solve this issue

You should be using #HTML.DropDownListFor, specifying a lambda that indicates which property in your model you want to bind the list's selected value to on the POST.
Given a view model like so:
public class MarksViewModel
{
public Marks Marks { get; set; }
public IEnumerable<SelectListItem> Drp_bind { get; set; }
}
The drop down list in the CSHTML can be declared like so:
#Html.DropDownListFor(m => m.Marks.StudentId, m.Drp_bind, "Select a Student")
The first argument is an expression describing the property on your model that you want to populate with the selected value from the drop down list in the post back. The second is the list comprising the values to which we need to data bind.
Note that your CSHTML will need more form fields within it bound to the other properties of the Marks property.
Your POST method would now take MarksViewModel as an argument and extract the Marks property from it to add to the DbContext for saving.

Related

Queue<T> type with Entity Framework Cast error

I have an entity A which holds a Queue<XYZ> B property. I want to persist it in a MySQL database. When migrating, the table is created correctly - each entity A has a table depicting Queue<XYZ> B. However, when I want to query the data from the database using:
A entityA = await _context.A.Include(entityA => entityA.B).FirstOrDefaultAsync((...));
Then I get such an error:
System.InvalidCastException: Unable to cast object of type 'System.Collections.Generic.Queue'1[API.Models.XYZ]' to type
'System.Collections.Generic.ICollection'1[API.Models.XYZ]'.
When I change the Queue<XYZ> B to List<XYZ> B then it works fine.
Is it impossible to automatically persist a queue to a database with Entity Framework?
Or do I have to do some extra work?
I have an entity A which holds a Queue B property. I want to
persist it in a MySQL database. When migrating, the table is created
correctly - each entity A has a table depicting Queue B. However,
when I want to query the data from the database using:
A entityA = await _context.A.Include(entityA => entityA.B).FirstOrDefaultAsync((...));
According to your description and the query statement, I have created a DeparmentViewModel with the Queue property, and reproduced the error when query the database using EF core.
public class DepartmentViewModel
{
[Key]
public int DepId { get; set; }
public string DepName { get; set; }
public Queue<EmployeeViewModel> EmployeeViewModels { get; set; }
}
To solve this issue, it seems that we could re-generate a Queue object based on the query result, like this:
DepartmentViewModel queryresult = _context.DepartmentViewModels
.Include(c=>c.EmployeeViewModels)
.Where(c => c.DepId==2) //
.Select(c=> new DepartmentViewModel()
{
DepId = c.DepId,
DepName = c.DepName,
EmployeeViewModels = new Queue<EmployeeViewModel>(c.EmployeeViewModels.ToList())
}).FirstOrDefault();
Besides, I also found that if using the Queue, when insert new data, it might cause the following error:
"System.InvalidOperationException: 'The type of navigation property 'EmployeeViewModels' on the entity type 'DepartmentViewModel' is 'Queue' which does not implement ICollection. Collection navigation properties must implement ICollection<> of the target type.'"
So, in my opinion, when you create Navigation Properties, try to use List<T> or ICollection<T>, instead of using Queue<T>.

Validate Unique Value in MVC5 and EF6

In my MVC application I have a requirement where I want user to insert Unique value in a column.
i.e.: Username should be unique in Users table.
I used [Indes(IsUnique = true)] data annotation in my model.
But when I insert duplicate value in the field it throws an exception, but I want to display an Error Message on my View saying Please try with a different Username
Please help me what should I do here?
You can use one of those:
Write your CustomValidator (ny recommendation)
[CustomRemoteValidator(ErrorMessage = #"Username already in use")]
public string Username{ get; set; }`
And override IsValid method
public override bool IsValid(object value)
{
return !(this.DbContext.Set<User>().Any(a =>
a.Username.Equals((string)value));
}
Check it in your business layer.
Check it before save entity in database by overriding SaveChanges() method.

Returning a subset of a navigation propertie's object

I have a one to many relationship as outlined below. In some parts of the business layer there are queries of the Item table and in others the Client table (as well as its Items). LazyLoading and ProxyCreation are both false, reference loop handling is set to ignore.
public class Client {
public virtual ICollection<Item> Items { get; set; }
public string Name {get;set;}
}
public class Item {
public virtual Client TheClient {get;set;}
public string ItemProp {get;set;}
// another 10 properties or so
}
myitems = dbContextScopeX.Items.Include(x => x.Client).ToList();
The view has a list of items with the need to show the Client's Name (in my example). I am looking for item.Client.Name ultimate, however when myitems gets queries/serialized it contains:
myitems.Client.Items
If I set the attribute [JsonIgnore] on the Client's Item property it never comes through the graph which I need it to in other places. Is there a way to get myItems.Client.Name without having to get myitems.Client.Items in the query or without having to create an anonymous projection for the Item array?
Project the Item properties you want (be they simple or complex type) along with just the Client name into an anonymous type and serialize that.
myitems = dbContextScopeX.Items.Include(x => x.Client)
.Select(i=>new {
ItemProp = i.ItemProp,
ItemCollection = i.ItemCollection,
...
ClientName = i.Client.Name
}).ToList();
Only caveat is you have to do some manual work if you want to deserialize this back into entities.

retrieve values from model in mvc2

I don't know how to create functions to retrieve the values.
*Table 1: OrgVasplans*
-Id
-vasplanId
-OrgId
-CreatedDate
Table-2: vasplans
-Id
-name
-amount
-validity
-vasdurationId
Table-3: VasDuration
Id
Duration.
These are my tables..
I have Controller named Candidatesvas and action method VasDetails....
I already stored the values into vasPlans table.
when I click in view "Details" link it will go to details page..
Then the values are retrieve from "Orgvasplans" table automatically without enter any input..
How to create methods for this....
I created some methods but the method contains only Name "field". I want to retrieve multiple values like "Amount", "validity" like that.....
Repository:
public IQueryable<VasPlan> GetVasPlans()
{
return from vasplan in _db.VasPlans
orderby vasplan.Name ascending
select vasplan;
}
public OrgVasPlan GetOrgVasPlan(int id)
{
return _db.OrgVasPlans.SingleOrDefault(v => v.Id == id);
}
public int AddOrgVasPlan(OrgVasPlan orgvasplan)
{
_db.OrgVasPlans.AddObject(orgvasplan);
Save();
return orgvasplan.Id;
}
public void AddVasPlan(VasPlan vasPlan)
{
_db.VasPlans.AddObject(vasPlan);
}
Controller
public ActionResult VasDetails(FormCollection collection)
{
OrgVasPlan orgvasplan = new OrgVasPlan();
orgvasplan.CreatedDate = DateTime.Now;
orgvasplan.OrgId = LoggedInOrganization.Id;
orgvasplan.vasplanId=??????????????
VasPlan vasplan = new VasPlan();
//if (!string.IsNullOrEmpty(collection["Name"])) ;
_repository.AddOrgVasPlan(orgvasplan);
_repository.Save();
return View();
}
Here i don't know how to put code here for get multiple values form vasplans table like(amount,name,validity etc...,)
this is my problem...
Make your view strongly-typed, make sure you create input elements whose names correspond to the model properties (or use HTML helpers, e.g. Html.TextBoxFor(model => model.Amount). That way MVC will automatically fill in the model for you when the action that should take the model as a argument, is invoked.
For example your action should be:
public ActionResult NewVasPlan(VasPlan vplan)
{
//check model state
//save or return error messages
}
Or you can simply add string and int parameters to the Action like this:
public ActionResult NewVasPlan(string name, int amount /*, etc*/)
{
//MVC will also automatically fill name, amount, from request POST or GET params
//(or cookies??)
}
Hope this helps, tell me if you need more info or if I misunderstood your question.

Using ListBoxFor in ASP.NET MVC 2

I am trying to update the Roles a specific group has in my application. The Group model I use in my view has an additional AllRoles IEnumerable attached to it, so that in my view I can do something like this:
<%: Html.ListBoxFor( model => model.aspnet_Roles, new MultiSelectList( Model.AllRoles, "RoleId", "RoleName" ), new { #class = "multiselect" } )%>
This generates a multiple select drop down as expected. However, coming form PHP, I noticed that the name of the select was without square brackets, maybe that is OK in ASP.NET but in PHP it is wrong.
Now, how do I go about updating the group after submiting the form, more precisely, how can I read the multiselct selected values. What I need is that based on the RoleIds that I receive to Add respective aspnet_Roles to my Group model.
Trying to read the received values using HttpContext.Request.Form["aspnet_Roles"] failed and is also ugly. Can I somehow use the model to fetch the needed data? Controller function:
[AcceptVerbs( HttpVerbs.Post )]
public ActionResult Edit( SYSGroups updatedGroup ) {}
Thanks
The selected ids will be sent as a collection:
[HttpPost]
public ActionResult Edit(string[] aspnet_Roles)
{
// the aspnet_Roles array will contain the ids of the selected elements
return View();
}
If the form contains other elements that need to be posted you could update your model:
public class SYSGroups
{
public string[] Aspnet_Roles { get; set; }
... some other properties
}
and have your action method look like this:
[HttpPost]
public ActionResult Edit(SYSGroups updatedGroup)
{
// updatedGroup.Aspnet_Roles will contain an array of all the RoleIds
// selected in the multiselect list.
return View();
}