I am building my first .NET Core MVC application and using the Entity Framework. A button call the AddtoOrder page which receives a set of parameters from the previous page, the AddtoOrder page is where the users are allowed to enter the Quantity that they would like to order. The model classes are like below
public class Item
{
public int CustomId { get; set; }
public Inventory Inventory { get; set; }
}
Where Inventory is another class
public partial class Inventory
{
public string Name { get; set; }
public int QuantityAvailable { get; set; }
public string RoomNumber { get; set; }
public int InventoryId { get; set; }
[NotMapped]
public int? QuantityReq { get; set; }
}
AddtoOrder view here QuantityReq
is the only field that the users will be entering others all retrieved from the DB.
@model JAXSurplusMouseApp.Models.Item
@{
ViewData["Title"] = "Edit";
}
<h4>Add to Order</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="AddtoOrder">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="@Model.Inventory.Name" class="control-label"></label>
<input asp-for="@Model.Inventory.Name" class="form-control" readonly />
</div>
<div class="form-group">
<label asp-for="@Model.Inventory.QuantityAvailable" class="control-label"></label>
<input asp-for="@Model.Inventory.QuantityAvailable" class="form-control" readonly />
</div>
<div class="form-group">
<label asp-for="@Model.Inventory.RoomNumber" class="control-label"></label>
<input asp-for="@Model.Inventory.RoomNumber" class="form-control" readonly />
</div>
</form>
<form method="post"
asp-controller="Inventories"
asp-action="OrderItem">
<label class="control-label">Quantity Required</label>
<input type="text" id="quantityReq" name="quantityReq" value=@Model.Inventory.QuantityReq />
@Html.ValidationSummary(false, "", new { @class = "error" })
<input type="hidden" id="customerID" name="customerID" value="@Model.CustomId" />
<input type="hidden" id="invetoryID" name="invetoryID" value="@Model.Inventory.InventoryId" />
<button type="submit"><u>Order</u></button>
</form>
</div>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
So I need to validate the user entered value against a value in the DB, so within the Controller, I am comparing the values like below where if the user entered quantity is greater than the quantity available in the DB else if (quantityReq > intData.QuantityAvailable)
in OrderItem
// Action to launch the AddtoOrder page
public async Task<IActionResult> AddtoOrder(int? inventoryID, int? custID)
{
if (inventoryID == null || custID == null)
{
return NotFound();
}
Customer custData = await _context.Customers.FindAsync(custID);
var inventories = await _context.Inventories.FindAsync(inventoryID);
var model = new Item
{
CustomId = (int)custID,
Inventory = inventories
};
return View(model);
}
//Action athat allows the users to submit the order
public async Task<IActionResult> OrderItem(int? customerID, int? invetoryID, int quantityReq)
{
if (customerID == null || invetoryID == null)
{
return NotFound();
}
Customer custData = await _context.Customers.FindAsync(customerID);
var intData = await _context.Inventories.FindAsync(invetoryID);
if (quantityReq <= intData.QuantityAvailable && quantityReq > 0)
{
InventoryOrder io = new InventoryOrder();
io.OrderQuantity = quantityReq;
io.InventoryId = (int)invetoryID;
_context.Add(io);
await _context.SaveChangesAsync();
intData.QuantityAvailable = intData.QuantityAvailable - quantityReq;
_context.Update(intData);
await _context.SaveChangesAsync();
return RedirectToAction("Index", "Inventories", new { id = customerID });
}
else if (quantityReq > intData.QuantityAvailable){
ModelState.AddModelError("QuantityReq", "Quantity entered more than Quantity Available");
return RedirectToAction("AddtoOrder", "Inventories", new { inventoryID = invetoryID, custID = customerID });
}
}
Since I am returning to a different view from the action the validation error is not showing on the AddtoOrder
page from the OrderItem
action. How can I handle the validation error!
CodePudding user response:
You can use TempData to store the validation fail flag like below:
[HttpGet]
public IActionResult AddtoOrder(int? inventoryID, int? custID)
{
if (inventoryID == null || custID == null)
{
return NotFound();
}
Customer custData = await _context.Customers.FindAsync(custID);
var inventories = await _context.Inventories.FindAsync(inventoryID);
var model = new Item
{
CustomId = (int)custID,
Inventory = inventories
};
//add the following code to judge if validation fail or not...
if(TempData["Error"]!=null)
{
ModelState.AddModelError("Inventory.QuantityReq", "Quantity entered more than Quantity Available");
}
return View(model);
}
[HttpPost]
public async Task<IActionResult> OrderItem(int? customerID, int? invetoryID, int quantityReq)
{
//...
else if (quantityReq > intData.QuantityAvailable)
{
TempData["Error"] = "Validation fail"; //add this...
return RedirectToAction("AddtoOrder", "Inventories", new { inventoryID = invetoryID, custID = customerID });
}
return View();
}