Home > Blockchain >  Server side validation for the user Input
Server side validation for the user Input

Time:11-01

I have a table in the web application from where the users can make orders. The table shows the Quantity that is available and we need to let users enter the quantity they need like below

enter image description here

when the Order button is clicked I want to validate if the user is entering the Quantity Required is greater than the Quantity Avail. Every time the Order button is clicked it calls the Controller to retrieve the data and check against the quantity. The view is like below

   @model JAXSurplusMouseApp.Models.CustomerInventoryCollectionDataModel

   @{
    ViewData["Title"] = "Index";
}

<h3>Order Surplus Mouse</h3>

 <div class="col-md-9">
  <table class="table">
   <thead>
    <tr>
     <th>
       Strain ID
     </th>
     <th>
       Strain Name
     </th>
     <th>
       Quantity Avail
     </th>
     <th>
       Room Number
     </th>
     <th>
       Quantity Required
     </th>
     <th></th>
    </tr>
   </thead>
   <tbody>
      @{var custID = Model.CustomerData; }
      @foreach (var item in Model.Inventorys)
      {
       <tr>
        <td>
          @Html.DisplayFor(modelItem => item.StrainId)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.StrainName)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.QuantityAvailable)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.RoomNumber)
        </td>
        <td>
         <form method="post"
               asp-controller="Inventories"
               asp-action="OrderItem">
         <row>
           <column>
             <input type="text" id="quantityReq" name="quantityReq" value=@item.QuantityReq size="4" />
             <input type="hidden" id="customerID" name="customerID" value="@custID.CustomerId" />
             <input type="hidden" id="invetoryID" name="invetoryID" value="@item.InventoryId" />
             <button type="submit" style="border: none; background-color: transparent; color: #1a0dab "><u>Order</u></button>
          </column>
        </row>
      </form>
    </td>
  </tr>
 }
 </tbody>
</table>
 @{
    var prevDisabled = !Model.Inventorys.HasPreviousPage ? "disabled" : "";
    var nextDisabled = !Model.Inventorys.HasNextPage ? "disabled" : "";
   }
   <a asp-action="Index"
      asp-route-sortOrder="@ViewData["CurrentSort"]"
      asp-route-pageNumber="@(Model.Inventorys.PageIndex - 1)"
      asp-route-currentFilter="@ViewData["CurrentFilter"]"
      class="btn btn-default @prevDisabled"> Previous </a>
    <a asp-action="Index"
       asp-route-sortOrder="@ViewData["CurrentSort"]"
       asp-route-pageNumber="@(Model.Inventorys.PageIndex   1)"
       asp-route-currentFilter="@ViewData["CurrentFilter"]"
       class="btn btn-default @nextDisabled"> Next </a>
    </div>
    </div>

And Controller action I am calling when clicking on the button is

public async Task<IActionResult> OrderItem(int? customerID, int? invetoryID, int quantityReq)
{
    if (customerID == null || invetoryID == null || quantityReq == 0)
    {
        return NotFound();
    }
    Customer custData = await _context.Customers.FindAsync(customerID);
    var intData = await _context.Inventories.FindAsync(invetoryID);

        if (quantityReq <= intData.QuantityAvailable)
        {
            MouseOrder mo = new MouseOrder();
            mo.CustomerId = (int)customerID;
            mo.OrderDate = DateTime.Now;
            mo.SamaccountName = "dvella";
            _context.Add(mo);
            await _context.SaveChangesAsync();

            InventoryOrder io = new InventoryOrder();
            io.OrderId = mo.MouseOrderId;
            io.OrderQuantity = quantityReq;
            io.InventoryId = (int)invetoryID;
            _context.Add(io);
            await _context.SaveChangesAsync();

            intData.QuantityAvailable = intData.QuantityAvailable - quantityReq;
            _context.Update(intData);
            await _context.SaveChangesAsync();                
        }

        else if (quantityReq > intData.QuantityAvailable){
        
             
        }

        return RedirectToAction("Index", "Inventories", new { id = customerID });
    }
     

Get action in the Controller is like below

    // GET: Inventories
public async Task<IActionResult> Index(int? id, string sortOrder, string searchString,
                                            int? pageNumber, string currentFilter)
    {
        if (id == null)
        {
            return NotFound();
        }
        ViewData["StockParam"] = String.IsNullOrEmpty(sortOrder) ? "st_desc" : "";
        ViewData["CurrentFilter"] = searchString;
        ViewData["CurrentSort"] = sortOrder;

        if (searchString != null)
        {
            pageNumber = 1;
        }
        else
        {
            searchString = currentFilter;
        }

        var inventories_data = from s in _context.Inventories
                               where s.QuantityAvailable >0
                            select s;
        if (!String.IsNullOrEmpty(searchString))
        {
            inventories_data = inventories_data.Where(s => s.StrainCode.Contains(searchString));
        }

        switch (sortOrder)
        {
            case "st_desc":
                inventories_data = inventories_data.OrderByDescending(s => s.StrainCode);
                break;
            default:
                inventories_data = inventories_data.OrderBy(s => s.StrainCode);
                break;
        }
        int pageSize = 15;

        Customer custData = await _context.Customers.FindAsync(id);
        var inventories = await PaginatedList<Inventory>.CreateAsync(inventories_data.AsNoTracking(), pageNumber ?? 1, pageSize);
        var model = new CustomerInventoryCollectionDataModel
        {
            CustomerData = custData,
            Inventorys = inventories
        };
        return View(model);

    }

Model Class is like

public class CustomerInventoryCollectionDataModel
    {
        public Customer CustomerData { get; set; }
        public PaginatedList<Inventory> Inventorys { get; set; }
    }

Where the Inventory Class is like

public partial class Inventory
{
    public string StrainId { get; set; }
    public string StrainName { get; set; }
    public int QuantityAvailable { get; set; }
    public string RoomNumber { get; set; }
    public int InventoryId { get; set; }

    [NotMapped]
    public int? QuantityReq { get; set; }
}

I am developing a web application for the first time using the .NET Core with EF and kind of stuck with this. Please Suggest me how can I handle the validation here. I am here not so particular where the validation message should be shown but a way to notify the users to enter the correct number. I appreciate all the help

****EDIT ****

I see the error like enter image description here

When I enter less or more than the the Quantity Available it is not doing anything, in the devtools I see the error like the screenshot

Uncaught SyntaxError: Function statements require a function name

Before pressing the Buy Now button the URL is like https://localhost:44330/Inventories/Index/460 Any after I pressed the https://localhost:44330/Inventories/Index/460#

I am not able to troubleshoot more , kind of stuck here

CodePudding user response:

try this. Since it is using ajax I removed a form and a submit button

 @model JAXSurplusMouseApp.Models.CustomerInventoryCollectionDataModel

   @{
    ViewData["Title"] = "Index";
}

<h3>Order Surplus Mouse</h3>

<table>
    <thead>
        <tr>
            <th style="padding-right:1em">
                Strain ID
            </th>
            <th style="padding-right:1em">
                Strain Name
            </th>
            <th style="padding-right:1em">
                Room
            </th>
            <th style="padding-right:1em">
                Quantity Avail
            </th>

            <th>
                Quantity Required
            </th>
    <tbody>

        @foreach(var item in Model.Inventorys)
        {
        <tr>
            <td />
            <td />
            <td />
            <td />
            <td style="padding-right:1em">
                <input type="text" class="text-danger float-right" style="border:none;font-size: smaller" id="@("errorMessage" @item.InventoryId)" readonly />
            </td>
        </tr>
        <tr style="padding-left:2em">
            <td>
                @Html.DisplayFor(modelItem => item.StrainId)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.StrainName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.RoomNumber)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.QuantityAvailable)
            </td>

            <td>
                <row>
                    <column>
                        <input type="text" style="text-align:right;padding-right:1em" id="@("quantityReq" @item.InventoryId)" name="quantityReq" value="@item.QuantityReq" /> &nbsp;&nbsp;
                    </column>
                    <column>
                        <input type="hidden" id="@("customer" @item.InventoryId)" name="customerID" value="@Model.CustomerData.Id" />
                        <input type="hidden" id="@("inventory" @item.InventoryId)" name="invetoryID" value="@item.InventoryId" />
                        <a href="#" id="buyNow" data-id="@item.InventoryId"> Buy now</a>
                </row>
            </td>
        </tr>
        }
    </tbody>
</table>

@section Scripts {

    <script type="text/javascript">
        $(document).ready(function () {
            $(document).on("click", "#buyNow", (function (e) {
                e.preventDefault();
                e.stopImmediatePropagation();

                 var id=$(this).data("id");
               
                 alert("Id: " id);

                onBuyNow(id);

            }));

            function onBuyNow(id) {

                var quantityReq = $("#quantityReq" id).val();
                var customerId = $("#customer" id).val();
                var data = {
                    customerId: customerId,
                    quantityReq: quantityReq,
                    inventoryId: id
                };

                alert(JSON.Stringify(data));

                $.ajax({
                    url: '@Url.Action("OrderItem", "Inventories")',
                    dataType: 'json',
                    type: 'POST',
                    data: data,
                    success: function (result) {
                    alert("result "   JSON.Stringify(result));

                    if (result !== "")
                    $("#errorMessage"   result.inventoryId).val("available only "   result.available);
                    else {
                            var url = '@Url.Action("Index", "Inventories")';
                            url=url  "?id=" customerId;
                            alert("url: "   url);
                            window.location.href = url;
                        };
                    error: function (error) {
                     alert("error");
                    }
                });
                };
            }
        });
    </script>
}

action

public async Task<JsonResult> OrderItem(int? customerID, int? inventoryID, int quantityReq)
{
    if (customerID == null || invetoryID == null || quantityReq == 0)
    {
        return NotFound();
    }
    Customer custData = await _context.Customers.FindAsync(customerID);
    var intData = await _context.Inventories.FindAsync(inventoryID);

        if (quantityReq <= intData.QuantityAvailable)
        {
           ... your code                
        }
        else if (quantityReq > intData.QuantityAvailable){
            return Json( new { inventoryId=inventoryId, available = intData.QuantityAvailable} );
        }
         return Json("");
}

and the bottom of a body section of your layout should have

<script src="~/lib/jquery/dist/jquery.min.js"></script>
@await RenderSectionAsync("Scripts", required: false)
  • Related