Answered by:
Best way to handle errors when posting data

Question
-
User982203039 posted
I have a form that posts data to a SQL database. For the most part this works fine. My issue is when there is an issue with the data I want it to redirect back to the form with the data still filled out but a message maybe what the issue is? Most of the time the issue is either a special character (which is another issue on how to replace special characters) and sometimes it is just simply too much text for what is defined in SQL. I believe most of this can be done in the controller post? Please give me some ideas!
public ActionResult CreateOrder(Order newOrder, string submit) { newOrder.Status = submit; if (ModelState.IsValid) { db.Orders.Add(newOrder); db.SaveChanges(); return RedirectToAction("Orders"); } else { return View(newOrder); } }
Wednesday, October 30, 2019 2:25 PM
Answers
-
User-821857111 posted
I would recommend that you use validation attributes on your model (if you aren't already) and include unobtrusive client side validation. In the majority of cases, this will result in the user being unable to submit the form if there are validation errors.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, October 30, 2019 2:37 PM -
User-474980206 posted
assuming you are using standard validation:
try { db.Orders.Add(newOrder); db.SaveChanges(); return RedirectToAction("Orders"); } catch (Exception ex) { ModelState.AddModelError("", formatError(ex)); return View(newOrder); }
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, October 30, 2019 2:57 PM -
User-821857111 posted
I did add [MaxLength(20)] to the modelLooks like you are using EF 6. MaxLength is mainly a configuration attribute, only it does cause DbEntityValidationExceptions at context level if it is exceeded as you have discovered. It doesn't work as an input validator in MVC. In other words, it won't cause validation to fail in MVC. You need StringLength for that. StringLength can be used to specify the max size of the database field too.- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, October 30, 2019 4:09 PM -
User-474980206 posted
I also tried:
try { db.Orders.Add(newOrder); db.SaveChanges(); return RedirectToAction("Orders"); } catch (Exception ex) { ModelState.AddModelError("", formatError(ex)); return View(newOrder); }
But it does not like
formatError
It says the Name formatError does not exist in the current context?
you need to write a format error function.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, October 30, 2019 5:38 PM
All replies
-
User-821857111 posted
I would recommend that you use validation attributes on your model (if you aren't already) and include unobtrusive client side validation. In the majority of cases, this will result in the user being unable to submit the form if there are validation errors.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, October 30, 2019 2:37 PM -
User-474980206 posted
assuming you are using standard validation:
try { db.Orders.Add(newOrder); db.SaveChanges(); return RedirectToAction("Orders"); } catch (Exception ex) { ModelState.AddModelError("", formatError(ex)); return View(newOrder); }
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, October 30, 2019 2:57 PM -
User982203039 posted
I tried this an purposely entered more then the 20 character limit on a field and I got the message message:
Here is the validator from my view:
@Html.ValidationMessageFor(model => model.OutstandingBalance, "", new { @class = "text-danger" })
I did add [MaxLength(20)] to the model - this might work for this one.
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.Exception Details: System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Source Error:
Line 241: {
Line 242: db.Orders.Add(newLoanOrder);
Line 243: db.SaveChanges();
Line 244: return RedirectToAction("Orders");
Line 245: }
Wednesday, October 30, 2019 3:18 PM -
User982203039 posted
I also tried:
try { db.Orders.Add(newOrder); db.SaveChanges(); return RedirectToAction("Orders"); } catch (Exception ex) { ModelState.AddModelError("", formatError(ex)); return View(newOrder); }
But it does not like
formatError
It says the Name formatError does not exist in the current context?
Wednesday, October 30, 2019 3:20 PM -
User1120430333 posted
I don't advice having any database logic in the controller. I don't advise having any business logic in the controller.
https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/
[HttpPost] public ActionResult Create(ArticleVM.Article article, string submit) { TempData["AuthorId"] = article.AuthorId; if (submit == "Cancel") return RedirectToAction("ArticleIndex", new { id = (int)TempData["AuthorId"] }); if (!ModelState.IsValid) return View(article); _articleDM.Add(article); return RedirectToAction("ArticleIndex", new {id = (int) TempData["AuthorId"]}); }
<copied>
An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.
In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.
<end>Wednesday, October 30, 2019 3:42 PM -
User-821857111 posted
I did add [MaxLength(20)] to the modelLooks like you are using EF 6. MaxLength is mainly a configuration attribute, only it does cause DbEntityValidationExceptions at context level if it is exceeded as you have discovered. It doesn't work as an input validator in MVC. In other words, it won't cause validation to fail in MVC. You need StringLength for that. StringLength can be used to specify the max size of the database field too.- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, October 30, 2019 4:09 PM -
User1120430333 posted
Baze72
I tried this an purposely entered more then the 20 character limit on a field and I got the message message:
Here is the validator from my view:
@Html.ValidationMessageFor(model => model.OutstandingBalance, "", new { @class = "text-danger" })
I did add [MaxLength(20)] to the model - this might work for this one.
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.Exception Details: System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Source Error:
Line 241: {
Line 242: db.Orders.Add(newLoanOrder);
Line 243: db.SaveChanges();
Line 244: return RedirectToAction("Orders");
Line 245: }
You could have just used a viewmodel that sits between the controller and view and validation would be done using the VM without EF throwing an exception as you try to persist the data to the database.
Do you see a try/catch? Do you see any database activity directly in the controller? You could put all the database logic in the class in the Models folder and call methods on the class in the Models folder for CRUD operations with the database, using the VM working with an EF model either mapping EF model data to VM or VM mapping data to EF model.
https://www.c-sharpcorner.com/article/managing-data-with-viewmodel-in-asp-net-mvc/
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace PublishingCompany.Models { public class AuthorVM { public class Author { public int AuthorID { get; set; } [Required(ErrorMessage = "First Name is required")] [StringLength(50)] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name is required")] [StringLength(50)] public string LastName { get; set; } } public List<Author> Authors { get; set; } = new List<Author>(); } }
using Microsoft.AspNetCore.Mvc; using PublishingCompany.Models; namespace PublishingCompany.Controllers { public class AuthorController : Controller { private IAuthorDM adm; public AuthorController(IAuthorDM authorDM) { adm = authorDM; } public IActionResult Index() { return View(adm.GetAll()); } public IActionResult Detail(int id = 0) { return id == 0 ? null : View(adm.Find(id)); } public IActionResult Create() { return View(adm.Add()); } [HttpPost] public ActionResult Create(AuthorVM.Author author, string submit) { if (submit == "Cancel") return RedirectToAction("Index"); if (!ModelState.IsValid) return View(author); adm.Add(author); return RedirectToAction("Index"); } public ActionResult Edit(int id = 0) { return id == 0 ? null : View(adm.Update(id)); } [HttpPost] public ActionResult Edit(AuthorVM.Author author, string submit) { if (submit == "Cancel") return RedirectToAction("Index"); if (!ModelState.IsValid) return View(author); adm.Update(author); return RedirectToAction("Index"); } public IActionResult Delete(int id = 0) { if (id > 0) adm.Delete(id); return RedirectToAction("Index"); } public ActionResult Cancel() { return RedirectToAction("Index", "Home"); } } }
Wednesday, October 30, 2019 5:36 PM -
User-474980206 posted
I also tried:
try { db.Orders.Add(newOrder); db.SaveChanges(); return RedirectToAction("Orders"); } catch (Exception ex) { ModelState.AddModelError("", formatError(ex)); return View(newOrder); }
But it does not like
formatError
It says the Name formatError does not exist in the current context?
you need to write a format error function.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, October 30, 2019 5:38 PM