SaveChanges in Edit action of MVC3 - c#

I'm a new to MVC and getting troubles with saving edited information of an action.
Every time I trying to SaveChanges I'm getting:
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
Here is my code:
[Authorize]
[HttpPost]
public ActionResult Profile(designer thisDesigner)
{
if (ModelState.IsValid)
{
db.Entry(thisDesigner).State = System.Data.EntityState.Modified;
try
{
db.SaveChanges();
}
catch (Exception)
{
return View(thisDesigner);
}
}
return RedirectToAction("Profile");
}
Also tried to query for new object and then to set and save the new values, in this case doesn't getting the exception, but the data is't saved.
Here is the code:
[Authorize]
[HttpPost]
public ActionResult Profile(designer thisDesigner)
{
designer updateDesigner = db.designers.Find(thisDesigner.designer_id);
if (ModelState.IsValid && updateDesigner != null)
{
db.Entry(updateDesigner).OriginalValues.SetValues(thisDesigner);
db.Entry(updateDesigner).State = System.Data.EntityState.Modified;
try
{
db.SaveChanges();
}
catch (Exception)
{
return View(thisDesigner);
}
}
return RedirectToAction("Profile");
}

Got it working :)
Just needed to add all properties of my model to page, like this:
#Html.HiddenFor(model => model.designer_id)
#Html.HiddenFor(model => model.designer_login_status)
#Html.HiddenFor(model => model.designer_register_date)
#Html.HiddenFor(model => model.designer_small_logo)
#Html.HiddenFor(model => model.designer_status)
#Html.HiddenFor(model => model.designer_vip_date)
And used same code from first example:
[Authorize]
[HttpPost]
public ActionResult Profile(designer thisDesigner)
{
if (ModelState.IsValid)
{
db.Entry(thisDesigner).State = System.Data.EntityState.Modified;
try
{
db.SaveChanges();
}
catch (Exception)
{
return View(thisDesigner);
}
}
return RedirectToAction("Profile");
}

Related

How to create the GET and POST methods 'CreateOrEdit()' to be redirected to CreateOrEdit.cshtml both when clicking on Edit and on Create New?

I am trying to customize a POST and GET method called CreateOrEdit(int id, Request request) inside of the controller so that when I am in the Index view which is a list of requests generated from a SQL Table and I click either on the Edit button on the right of each row or on the Create New button, I am redirected to the same View which I have called CreateOrEdit.cshtml. I have managed to make the configuration on RouteConfig.cs but I don't how to come up with an 'if - else' condition in order to check whether id is null or is a number. Someone could help me on solving this?
P. s.: Maybe this is children easy but today is my 9th day as a developer guys :)
I have tried:
1. Add another 2 routes.MapRoute() inside RouteConfig.cs
2. Inside the ActionResult CreateOrEdit() GET and POST methods tried to add a condition in order to know whether id != null but it doesn't seem to help.
[HttpGet]
public ActionResult CreateOrEdit(int? id)
{
return View();
}
[HttpPost]
public ActionResult CreateOrEdit(int? id, Request request)
{
if (/* id is not null (Edit has been clicked) */)
{
try
{
using (DbModels dbModel = new DbModels())
{
dbModel.Requests.Add(request);
dbModel.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
else
{
try
{
// Ketu shtojme logjiken e update-imit
using (DbModels dbModel = new DbModels())
{
dbModel.Entry(request).State = System.Data.EntityState.Modified;
dbModel.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
return View();
}
first your condition is wrong. so just change your condition and then try.
[HttpPost]
public ActionResult CreateOrEdit(int? id, Request request)
{
if (id == null)
{
try
{
using (DbModels dbModel = new DbModels())
{
dbModel.Requests.Add(request);
dbModel.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
else
{
try
{
// Ketu shtojme logjiken e update-imit
using (DbModels dbModel = new DbModels())
{
dbModel.Entry(request).State = System.Data.EntityState.Modified;
dbModel.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
return View();
}**strong text**

How can I return to the form after server side validation with form data intact?

I have this validation rule to compare two dates:
public class EmployeeAbsenceValidator : AbstractValidator<EmployeeAbsence>
{
public EmployeeAbsenceValidator() {
RuleFor(a => a.DateTo)
.GreaterThanOrEqualTo(a => a.DateFrom);
}
}
This is the controller code for validating a newly created absence period:
if (ModelState.IsValid)
{
EmployeeAbsenceValidator validator = new EmployeeAbsenceValidator();
ValidationResult result = validator.Validate(employeeAbsence);
if (!result.IsValid)
{
return RedirectToAction("Create", "EmployeeAbsences");
}
else
{
_context.Add(employeeAbsence);
await _context.SaveChangesAsync();
return RedirectToAction("Details", "Employees");
}
}
If the dates are not valid, I want to return to the form with all the form data intact. How do I do that?
Assuming the Action name is the same for your GET and POST action methods, then use return this.View( model ), like so:
if (ModelState.IsValid)
{
EmployeeAbsenceValidator validator = new EmployeeAbsenceValidator();
ValidationResult result = validator.Validate(employeeAbsence);
if (!result.IsValid)
{
return this.View( employeeAbsence );
}
else
{
_context.Add(employeeAbsence);
await _context.SaveChangesAsync();
return RedirectToAction("Details", "Employees");
}
}
This will return the page's HTML to the POST request with those validation error messages inside any #Html.ValidationMessageFor( m => m.Foo helpers (or <span asp-validator-for="Foo"> helpers).

ASP - MVC entity Framework Update of records, does not update if only appended with characters other than the original data

I have this problem of updating records in which it only updates when the original data in the Edit textbox was totally changed with a new value. if the origial value for example is "Apple" and only appended with 'S' to become "Apples" it does not update. it only updates when the entire word will be changed. i used an entity framework to create my data model for the table I created.and used Edit scaffold template for the Edit Form View. Can you help me with this one?
Here's my code in Edit Controller Actions:
public ActionResult Edit(int? Id)
{
// if (Id == null)
// {
// return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
// }
Book student = stud.Books.Find(Id);
//if (student == null)
//{
// return HttpNotFound();
// }
return View(student);
}
//edit2
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult EditPost(int? Id)
{
//if (Id == null)
//{
//return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
//}
var studentToUpdate = stud.Books.Find(Id);
if (TryUpdateModel(studentToUpdate, "",
new string[] { "BookTitle", "Author"}))
{
try
{
if (ModelState.IsValid)
{
stud.SaveChanges();
return RedirectToAction("Index");
}
}
catch
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
return View(studentToUpdate);
}

Edit order details in ASP.NET MVC

The standard way to edit a record in ASP.NET MVC is the following:
//
// GET: /Movies/Edit/5
public ActionResult Edit(int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
//
// POST: /Movies/Edit/5
[HttpPost]
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
The problem is that I need to edit order details (1 order, many details) and therefore based on two IDs (the order and the product ones). It does not work (I cannot get an OrderDetail item as action parameter). How can I solve this problem?
Thanks.
//
// GET: /Orders/EditDetails
public ActionResult EditDetails(int id, string productID)
{
OrderDetail od = GetOrderDetail(id, productID);
return View(od);
}
//
// POST: /Orders/EditDetails
[HttpPost]
public ActionResult EditDetails(OrderDetail od)
{
if (ModelState.IsValid)
{
context.Entry(od).State = EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index");
}
return View(od);
}
EDIT: Here is the code requested by Shimmy:
#using (Html.BeginForm("EditDetails", "Orders", FormMethod.Post))
{
#Html.LabelFor(m => m.quantity)
#Html.TextBoxFor(m => m.quantity)
#Html.LabelFor(m => m.productID)
#Html.DropDownListFor(m => m.productID, new SelectList((IEnumerable)ViewBag.productList, "productID", "fullProductName"))
#Html.HiddenFor(model => model.orderID)
}
Make sure the OrderDetail.Id itself as well as the OrderDetail.OrderId and the OrderDetail.MovieId properties are all present in the form as a hidden field.
In that way, when you post it back to the server you have track on what Movie and Order this OrderDetail is of, in the action.

The ViewData item that has the key 'JobTitleID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'?

Following a tutorial, and have followed it step-by-step but get an error when I want to edit a field.
Source Error:
</div>
<div class="editor-field">
#Html.DropDownList("JobTitleID", String.Empty)
#Html.ValidationMessageFor(model => model.JobTitleID)
</div>
Here's my controller:
// POST: /Employee/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "SIN, FirstName, MiddleName, LastName, StartDate, Salary, JobTitleID, DepartmentID")] Employee employee)
{
try
{
if (ModelState.IsValid)
{
db.Employees.Add(employee);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException dex)
{
if (dex.InnerException.InnerException.Message.Contains("IX_Employee_SIN"))
{
ModelState.AddModelError("SIN", "Unable to save changes. Remember, you cannot have duplicate SIN numbers.");
}
else
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
}
DepartmentDropDownList(employee.DepartmentID);
JobDropDownList(employee.JobTitleID);
return View(employee);
}
//
// GET: /Employee/Edit/5
public ActionResult Edit(int id = 0)
{
Employee employee = db.Employees.Find(id);
if (employee == null)
{
return HttpNotFound();
}
DepartmentDropDownList(employee.DepartmentID);
JobDropDownList(employee.JobTitleID);
return View(employee);
}
//
// POST: /Employee/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID, SIN, FirstName, MiddleName, LastName, StartDate, Salary, JobTitleID, DepartmentID")] Employee employee)
{
try
{
if (ModelState.IsValid)
{
db.Employees.Add(employee);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException dex)
{
if (dex.InnerException.InnerException.Message.Contains("IX_Employee_SIN"))
{
ModelState.AddModelError("SIN", "Unable to save changes. Remember, you cannot have duplicate SIN numbers.");
}
else
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
}
DepartmentDropDownList(employee.DepartmentID);
JobDropDownList(employee.JobTitleID);
return View(employee);
}
private void JobDropDownList(object selectedJob = null)
{
var dQuery = from d in db.JobTitles
orderby d.Title
select d;
ViewBag.JobID = new SelectList(dQuery, "ID", "Title", selectedJob);
}
private void DepartmentDropDownList(object selectedDepartment = null)
{
var dQuery = from d in db.Departments
orderby d.DepartmentName
select d;
ViewBag.DepartmentID = new SelectList(dQuery, "ID", "DepartmentName",selectedDepartment);
}
I'm not really that familiar with MVC, just thought I'd ask what the issue is, and how it can be fixed.
The ViewBag encapsulate the ViewData internally, so, the message you are getting is about the ViewBag. You have setted the ViewBag.JobID on the controller and in your view you are trying to use another key, JobTitleID. Try using the right key:
#Html.DropDownList("JobID", String.Empty)

Categories

Resources