EF Insert Child to specific Parent - c#

I have been searching all over the place, found many questions but neither of them answer my.
Thing I am trying to do is simple, let's say we have something like that:
public class Parent
{
public int ID { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public int ID { get; set; }
public int ParentID { get; set; }
public Parent Parent { get; set; }
}
EF takes care of creating db and via scaffolding I get controllers and views. Everything works fine, I can create Parent. I can also create Child with ParentID chosen from drop down.
What I really want to do is remove drop down and pass ParentID as parameter like that:
public IActionResult Create(int id)
{
if (id == 0)
{
return NotFound();
}
ViewData["ID"] = id; //that a ParentID
return View();
}
And in view we got this:
<form asp-action="Create">
<div class="form-horizontal">
<h4>Child</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="ParentID" value=#ViewData["ID"] />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
When submitting this I got "Cannot insert explicit value for identity column in table 'Children' when IDENTITY_INSERT is set to OFF." Now I looked all over the place and tried various attributes yet still I can't get this to work.
I will be grateful for any sort of help.
Update
Create method from controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,ParentID")] Child child)
{
if (ModelState.IsValid)
{
_context.Add(child);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(book);
}
Just to show more about problem. Here I am using default scaffolded version with select control in view.
public IActionResult Create(int id)
{
if (id == 0)
{
return NotFound();
}
ViewData["ParentID"] = new SelectList(_context.Parents.Where(x => x.ID == 1), "ID", "ID"); //Works
ViewData["ParentID"] = new SelectList(_context.Parents.Where(x => x.ID == id), "ID", "ID"); // Doesn't work
return View();
}

After talking with people in comments I start to think that problem is caused by a bug in EF Core but I think I have found 'dirty' work around.
Here is Child model:
public class Child
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ParentID { get; set; }
[ForeignKey("ParentID")]
public Parent Parent { get; set; }
}
Now (for some reason) this solves "Cannot insert explicit value for identity column in table 'Children' when IDENTITY_INSERT is set to OFF." issue but creates new, we don't get unique id. I fixed that by making it myself, here is create method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,ParentID")] Child child)
{
if (ModelState.IsValid)
{
int _id;
do
{
_id = new Random().Next();
} while (await _context.Children.Where(b => b.ID == _id).AnyAsync());
child.ID = _id;
_context.Add(child);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewData["ID"] = id;
return View(child);
}
Now doWhile makes sure that we don't assign the same id to two different objects. Alternatives to Random option are to use Guid (when id is string) or GetHashCode (and increment in case of collision perhaps).

Related

Object posted through form is changed and its id is set to different one

When i post a form, vehicle id is set correctly but in my object named Order all properties are null and id is set to vehicle id.
Sorry for my poor explanation but i'm not sure how to describe it.
Everything is fine when i debug GET method and view but when it comes to POST method and i hover my mouse above method parameters, Order selected.id is already the same as int id
Here's my code:
View model:
public class AssignOrderViewModel
{
public Vehicle Vehicle { get; set; }
public List<Order> OrderList { get; set; }
public Order SelectedOrder { get; set; }
}
Order model:
public class Order
{
public int Id { get; set; }
public Address PickUpAddress { get; set; }
public Address DropOffAddress { get; set; }
public DateTime PickUpTime { get; set; }
public DateTime DropOffTime { get; set; }
public OrderState OrderState { get; set; }
public List<Vehicle> AssignedVehicles { get; set; }
public List<Cargo> Cargo { get; set; }
}
Controller GET action:
public async Task<IActionResult> AssignOrder(int? id, int? selectedOrderId)
{
if (id == null)
{
return NotFound();
}
var vehicle = await _context.Vehicles
.Include(v => v.LoadingSpace)
.Include(v => v.Position)
.FirstOrDefaultAsync(m => m.Id == id);
if (vehicle == null)
{
return NotFound();
}
var orderList = new List<Order>(_context.Orders.Include(o => o.PickUpAddress).Include(o => o.DropOffAddress).Include(o => o.Cargo).Include(o => o.AssignedVehicles).Include("Cargo.CargoUnit"));
Order selectedOrder = null;
if (selectedOrderId != null)
selectedOrder = orderList.Where(o => o.Id == selectedOrderId).FirstOrDefault();
AssignOrderViewModel assignOrderViewModel = new AssignOrderViewModel
{
Vehicle = vehicle,
OrderList = orderList,
SelectedOrder = selectedOrder
};
return View(assignOrderViewModel);
}
Controller POST action:
[HttpPost, ActionName("AssignOrder")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> OrderAssigned(int id, [Bind("Id,OrderState")] Order selected)
{
var vehicle = await _context.Vehicles.FindAsync(id);
if (selected.OrderState == OrderState.NotAssigned)
{
var order = await _context.Orders.FindAsync(selected.Id);
order.OrderState = OrderState.WaitingForPickUp;
}
vehicle.CurrentOrderId = selected.Id;
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
AssignOrder.cshtml view
This one is quite big so i will try to show most important parts:
Model:
#model TransportationManagementSystem.Models.AssignOrderViewModel
Selection of order:
Its working properly, sends get and page is refreshed, selected order is highlighted.
#foreach (var order in Model.OrderList)
{
<a class="text-body order-element" asp-action="AssignOrder" asp-route-selectedOrderId="#order.Id">
<div class="card my-3">
<div class="card-body order-element
#if (Model.SelectedOrder != null)
{
#(order.Id == Model.SelectedOrder.Id ? "selected-order" : "")
} ">
...
Post form: I think that its something wrong here.
<form asp-action="AssignOrder">
<input type="hidden" asp-for="Vehicle.Id" />
<input type="hidden" asp-for="SelectedOrder" />
<button type="submit" class="btn btn-primary mt-2">Assign</button>
</form>
...
I tried removing input with Vehicle.Id, id was still set for vehicle and order id was still set as vehicle id.
I also tried: <input [...] value="#Model.SelectedOrder" /> but it still didn't work.
What am i doing wrong?

Drop down list value doesn't seem to make it into the database for MVC 5

I'm trying to create a drop down list that will let you specify which company an employee works for. Below is my EmployeeViewModel. CompanyId is a foreign-key constrained database field which links to the Company table.
public class EmployeeViewModel
{
public EmployeeViewModel()
{
}
public EmployeeViewModel(Employee Employee, string CompanyName)
{
Initialize(Employee, CompanyName);
}
public EmployeeViewModel(Employee Employee, CliFFEntities db)
{
Initialize(Employee, db.Companies.Find(Employee.CompanyId).Name);
}
private void Initialize(Employee employee, string CompanyName)
{
this.Id = employee.Id;
this.Name = employee.Name;
this.CompanyId = employee.CompanyId;
this.InternalId = employee.InternalId;
this.CompanyName = CompanyName;
}
public int Id { get; set; }
public string Name { get; set; }
public Nullable<int> InternalId { get; set; }
[Display(Name = "Company")]
public int CompanyId { get; set; }
public String CompanyName { get; set; }
//public List<Company> CompanyList { get; set; }
public IEnumerable<SelectListItem> CompanyList { get; set; } //to be set in controller on an as-needed basis
}
Relevant part of the Employees controller:
// GET: Employees/Create
public ActionResult Create()
{
var evm = new EmployeeViewModel();
evm.CompanyList = new SelectList(db.Companies, "Id", "Name");
return View(evm);
}
Relevant part of my create view:
<div class="form-group">
#Html.LabelFor(m => m.CompanyId)
<div class="col-md-10">
#Html.DropDownListFor(m => m.CompanyId, Model.CompanyList)
#Html.ValidationMessageFor(m => m.CompanyId)
</div>
</div>
So all that seems to work fine. In fact, when I look at the post data it even sets the CompanyId to the correct value, corresponding to a company ID in the database.
But if I enforce the foreign key on the database side, it throws an error because that CompanyId doesn't seem to make it into the Employee record. If I turn off the FK constraint, the CompanyId just shows up as a 0.
What gives?
Welp, looks like I'm so new to MVC 5 that I didn't realize that there's such thing as a post method. Here's what I changed it to to map the EmployeeViewModel back to Employee:
// POST: Employees/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,CompanyId,InternalId")] EmployeeViewModel evm)
{
var employee = new Employee { Name = evm.Name, CompanyId = evm.CompanyId, InternalId = evm.InternalId };
if (ModelState.IsValid)
{
db.Employees.Add(employee);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(employee);
}

How do i save a new record with a foriegn key using entity framework?

So I have two models, Product and Review. The Product model contains a navigation property called Review as seen below:
Public class Product
{
[HiddenInput(DisplayValue=False])
public int ProductID {get; set;}
[Required]
public string ProductName {get; set;}
[HiddenInput(DisplayValue=False)
public ICollection<Reviews> {get; set;}
}
The the Review model:
public class Review
{
[HiddenInput(DisplayValue=false)]
public int ReviewId { get; set; }
[Required]
public int ProductID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Subject { get; set; }
[Required]
public string Body { get; set; }
}
I have an Action ViewResult method for ProductDetails where it fetches all Products plus all the reviews which has the same FK ProductIDs as seen here below:
public ViewResult ProductDetails(int productId)
{
Product product = repository.Products
.Include(p => p.Reviews)
.FirstOrDefault(p => p.ProductID == productId);
return View(product);
}
Then there is a View Which contains very simple HTML elements you can see it below:
#model app.models.Product
#Html.DisplayFor(model => model.ProductName)
#foreach (var review in Model.Reviews)
{
#Html.Partial("_Reviews", review)
}
Within above view I called for a partial view to render all reviews belong to that specific product. In the Partial view i have a form where the user can submit a review. I want the user to submit a review for the Product which the name is at the top of the view. I know i have to create an action for this but the only thing makes me uncomfortable with it is that i can't figure out how to get the ProductID of that specific Product.
Edit:
As per Stephen's answer I had to put the form Html elements into the main view which is ProducDetails and had put some scripts to call Json result to save data in the database.
Controller method to save the Review:
[HttpPost]
public JsonResult CreateReview (Review review)
{
if (review.ReviewId == 0)
{
db.Reviews.Add(review);
}
else
{
Review dbEntry = db.Reviews.Find(review.ReviewId);
if (dbEntry != null)
{
dbEntry.ProductID = review.ProductID;
dbEntry.Name = review.Name;
dbEntry.Subject = review.Subject;
dbEntry.Body = review.Body;
}
}
db.SaveChanges();
return Json(true);
}
You're wanting to create a new Review for the Product so the form needs to be in the main view, not the partial. The following assumes you want to submit using ajax and update the list of existing reviews
#model app.models.Product
#Html.DisplayFor(model => model.ProductName)
// display existing reviews
<div id="reviews">
#foreach (var review in Model.Reviews)
{
#Html.DisplayFor(m => review.Body)
}
</div>
<h2>Create new Review</h2>
#Html.Partial("_NewReview", new Review(){ ProductID = Model.ProductID })
Where _NewReview.cshtml is
#model Review
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.ProductID)
#Html.EditorFor(m => m.Name)
#Html.EditorFor(m => m.Subject)
#Html.TextAreaFor(m => m.Body)
<input id="create" type="submit" value="Create" />
}
and delete the _Reviews.cshtml file
Then in the main view, add the following script
var url = '#Url.Action("Create", "Review")';
var reviews = $('#reviews');
var form = $('form');
$('#create').click(function() {
$.post(url, form.serialize(), function(response) {
if (response) {
reviews.append($('#Body').val()); // add the new Review to the existing reviews
form.get(0).reset(); // reset the form controls
}
}).fail(function (result) {
// oops
});
return false; // cancel the default submit
});
which will submit to (in ReviewController)
[HttpPost]
public JsonResult Create(Review model)
{
// Save the model
return Json(true); // return something to indicate success
}
As i can imagine ProductId is unique
In Your Partial View you can Write your code inside Ajax.BeginForm
#model Review
#Ajax.BeginForm("ActionName", "ControllerName", new { productId = Model.ProductId }, #*AjaxOptions Attribute*#)
{
Review Fields here
<input type="submit" value="Submit Review"/>
}
To get the ProductID, you have add the ForeignKey of the Product Table in the Review Table.
public class Review
{
[HiddenInput(DisplayValue=false)]
public int ReviewId { get; set; }
[Required]
public int ProductID { get; set; }
[Required]
[ForeignKey("ProductID")]
publiv virtual Product {get;set;}
}
hope this helps

EF 6 SaveChanges with multiple references to same (changed) object

I have a class with two references to the same class. When updating the main class, I may also update the referenced class. When I have two references to the same (modified) object, I get an InvalidOperationException:
Attaching an entity of type 'ns.entity' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
Simple example:
public class Example {
public int OldestFriendId {get; set;}
public int BestFriendId {get; set;}
public virtual Friend Oldest {get; set; }
public virtual Friend Best {get; set; }
}
If while updating Example, I want to update the Middle name of my Oldest/Best friend, it works as long as they aren't the same. But if they are the same, then I get the above exception.
I can't figure out how to get this to work. I've tried setting references to null, saving them independently of the parent class, setting all references in them to null (EF is automatically creating two list of Examples in Friend).
How can I save an object that has changed when there are multiple references to it?
UPDATE: not yet working the way I want, but I have had some progress after removing the list of Examples from Friend. Also, the update is the result of a POST. Still investigating...
As sample code was asked for...this is from a post on a web app, no change was actually made
public ActionResult SaveEdit(int id, [Bind(Include = "OldestFriendId, BestFrinedId, Oldest, Best")] Example example)
{
if (ModelState.IsValid)
{
using (((WindowsIdentity)ControllerContext.HttpContext.User.Identity).Impersonate())
{
using (var _db = new exampleEntities())
{
//example.Best= example.Oldest; // this line would allow the update to work.
//next line is where the exception occurs
_db.Entry(example).State = EntityState.Modified;
_db.SaveChanges();
}
}
}
}
The EditorFor template:
#model Testing.Friend
<div class="col-md-10">
#Html.HiddenFor(model => model.FriendId)
#Html.EditorFor(model => model.FirstName)
#Html.EditorFor(model => model.LastName)
</div>
The Edit view for Example
#model Testing.Example
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Example</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ExampleId)
<div class="form-group">
#Html.LabelFor(model => model.OldestFriendId, "OldestFriendId", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.HiddenFor(model => model.OldestFriendId)
#Html.EditorFor(model => model.Oldest)
</div>
<div class="form-group">
#Html.LabelFor(model => model.BestFriendId, "BestFriendId", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.HiddenFor(model => model.BestFriendId)
#Html.EditorFor(model=> model.Best)
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
EDIT
The most likely cause is because when you retrieve the object back, it deserializes the 2 friends as 2 completely different objects (even when they are the same). Same problem as below, but rather than EF deserializing into 2 objects, ASP.NET MVC is doing it.
What you will have to do is something like the following:
Check if the 2 Friend ID's are the same (as ID is the PK). If not continue as normal
If they have the same ID, check if the 2 friend objects are the same.
If they are the same go to step 5.
Combine the changes together, however you want to deal with conflicts.
Set one of the Freinds to the same as the other Friend reference, e.g. Best = Oldest
SaveChanges()
Original Answer
My guess is that this is the classic problem of Include when you are retrieving the data.
When you do
Context.Examples.Include(x => x.Oldest).Include(x => x.Best).ToList()
What is happening is EF will create TWO objects of friend(Oldest and Best), even if they point to the same record. This is a known problem with include.
So when you go to save after update, EF sees them as 2 separate entities with the same key (and data) and complains.
If this is the case you have a couple of options:
Retrieve a list of all Friends for the current example and then the Example without the include
Let EF use LazyLoading and load the Friends when and as you need them.
My solution to the problem was to stop binding the whole object, and bind to the individual objects.
public ActionResult SaveEdit(int id, [Bind(Include = "OldestFriendId, BestFrinedId")] Example example,
Bind(Prefix="Oldest", Include = "FriendId, FirstName, MiddleName, LastName")] Friend oldest,
Bind(Prefix="Best", Include = "FriendId, FirstName, MiddleName, LastName")] Friend best) {
if (ModelState.IsValid)
{
using (((WindowsIdentity)ControllerContext.HttpContext.User.Identity).Impersonate())
{
using (var _db = new exampleEntities())
{
// do whatever processing you want on best and/or oldest
example.BestFriendId = best.FriendId;
example.OldestFriendId = oldest.FriendId;
_db.Entry(example).State = EntityState.Modified;
_db.SaveChanges();
}
}
}
}
EDIT: Replaced with full sample code
This example works for me.
I think is does what you are trying.
using System;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Migrations;
namespace Ef6Test {
public class Program {
public static void Main(string[] args) {
ExecDb1();
}
private static void ExecDb1() {
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Ef6Ctx, Ef6MigConf>());
WhichDb.DbName = "MSAMPLEDB";
WhichDb.ConnType = ConnType.CtxViaDbConn;
var sqlConn = GetSqlConn4DBName(WhichDb.DbName);
var context = new Ef6Ctx(sqlConn);
context.Database.Initialize(true);
Console.WriteLine(WhichDb.DbName, context.Database.Exists() );
AddJunk(context);
}
public static class WhichDb {
public static string DbName { get; set; }
public static string ConnectionName { get; set; }
public static ConnType ConnType { get; set; }
}
public enum ConnType {
CtxViaDbConn,
CtxViaConnectionName
}
private static void AddJunk(DbContext context) {
var friend = new Friend();
friend.Name = "Fred";
friend.Phone = "555-1232424";
context.Set<Friend>().Add(friend);
context.SaveChanges();
// break here and check db content.
var eg = new Example();
eg.Best = friend; // set them equal
eg.Oldest = friend;
friend.Name = "Fredie"; // change the name of the fly
friend.Phone = "555-99999"; // and phone is also different
context.Set<Example>().Add(eg); Add the new example
context.SaveChanges();
// result... 2 records.
// The original friend record should be chnaged
}
public static DbConnection GetSqlConn4DBName(string dbName) {
var sqlConnFact = new SqlConnectionFactory(
"Data Source=localhost; Integrated Security=True; MultipleActiveResultSets=True");
var sqlConn = sqlConnFact.CreateConnection(dbName);
return sqlConn;
}
}
public class MigrationsContextFactory : IDbContextFactory<Ef6Ctx> {
public Ef6Ctx Create() {
switch (Program.WhichDb.ConnType) {
case Program.ConnType.CtxViaDbConn:
var sqlConn = Program.GetSqlConn4DBName(Program.WhichDb.DbName); //
return new Ef6Ctx(sqlConn);
case Program.ConnType.CtxViaConnectionName:
return new Ef6Ctx(Program.WhichDb.ConnectionName);
default:
throw new ArgumentOutOfRangeException();
}
}
}
public class Ef6MigConf : DbMigrationsConfiguration<Ef6Ctx> {
public Ef6MigConf() {
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
}
public class Friend {
public int Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
}
public class Example
{
public int Id { get; set; }
public int? BestFriendId { get; set; }
public int? OldestFriendId { get; set; }
public virtual Friend Best { get; set; }
public virtual Friend Oldest { get; set; }
}
public class Ef6Ctx : DbContext {
public Ef6Ctx(DbConnection dbConn) : base(dbConn, true) { }
public Ef6Ctx(string connectionName) : base(connectionName) { }
public DbSet<Friend> Friends { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Example>()
.HasOptional(t=>t.Best)
.WithMany()
.HasForeignKey(x=>x.BestFriendId);
modelBuilder.Entity<Example>()
.HasOptional(t => t.Oldest)
.WithMany()
.HasForeignKey(x => x.OldestFriendId);
}
}
}

The UPDATE statement conflicted with the FOREIGN KEY constraint in asp.net mvc 5

I am getting this error:
The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_TitleMember". The conflict occurred in database "ParishDBSQL", table "dbo.Titles", column 'title_id'.
The statement has been terminated.
controller
Get Action
public ActionResult Edit(int? id)
{
var member = (from h in db.Members
join f in db.Titles on h.title_id equals f.title_id
where h.m_id == id
select new
{
title_id = h.title_id,
}).First();
var viewmodel = new MembersViewModel();
viewmodel.title_id = member.title_id;
ViewBag.Titles = new SelectList(db.Titles.ToList(), "title_id", "Titles", viewmodel.title_id);
return View(viewmodel);
}
Post Action
public ActionResult Edit(MembersViewModel vm)
{
if (ModelState.IsValid)
{
var member = db.Members.Find(vm.m_id);
member.title_id = vm.title_id;
ViewBag.Titles = new SelectList(db.Titles.ToList(), "title_id", "Titles", vm.title_id);
db.Members.Attach(member);
db.Entry(member).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vm);
View
<div class="col-md-4">
<div class="form-group">
<label>Title</label>
#Html.DropDownList("Titles")
#Html.ValidationMessageFor(model => model.title_id)
</div>
</div>
Model
public partial class Title
{
public Title()
{
this.Heads = new HashSet<Head>();
this.Members = new HashSet<Member>();
}
public int title_id { get; set; }
public string Titles { get; set; }
public virtual ICollection<Head> Heads { get; set; }
public virtual ICollection<Member> Members { get; set; }
}
Viewmodel
public class MembersViewModel
{
public int m_id { get; set; }
public string titles { get; set; }
public int title_id { get; set; }
}
I want to update a title_id using a dropdownlist on my members table table but I get the error that is shown above.
i think that the error is in this line
member.title_id = vm.title_id
maybe vm.title_id it is not found in primary table and it could not be a foreign key. Check the correct value of this variable
if it doesn't solve your problem looking at your code I saw some thinghs that I didn't understand very well.
try to change your code in this way
if (ModelState.IsValid)
{
var member = db.Members.Find(vm.m_id);
member.title_id = vm.title_id;
ViewBag.Titles = new SelectList(db.Titles.ToList(), "title_id", "Titles", vm.title_id);
db.SaveChanges();
return RedirectToAction("Index");
}
Usually I use db.Entry(member).State = EntityState.Modified; if I have to do other changes before db.SaveChanges();
member is already attched to your table. Why do you db.Members.Attach(member);
update
change
#Html.DropDownListFor(m => m.title_id, ViewBag.Titles)
into
#Html.DropDownListFor(m => m.title_id, (SelectList) ViewBag.Titles)
because ViewBag is a dynamic object
The problem is the drop down list in the view. You really want to initialize it like this:
#Html.DropDownListFor(m => m.title_id, ViewBag.Titles)
The way you're initializing it now causes the selected value to be passed as a query string parameter - you should see the URL being posted to as ...?Titles=1 for example.

Categories