用户输入的服务器端验证
Posted
技术标签:
【中文标题】用户输入的服务器端验证【英文标题】:Server side validation for the user Input 【发布时间】:2021-12-13 18:13:58 【问题描述】:我在 Web 应用程序中有一个表格,用户可以在其中下订单。该表显示了可用的数量,我们需要让用户输入他们需要的数量,如下所示
当单击订单按钮时,我想验证用户输入的所需数量是否大于可用数量。每次单击 Order 按钮时,它都会调用 Controller 来检索数据并检查数量。视图如下所示
@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>
点击按钮时我调用的控制器操作是
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: 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);
模型类是这样的
public class CustomerInventoryCollectionDataModel
public Customer CustomerData get; set;
public PaginatedList<Inventory> Inventorys get; set;
Inventory 类在哪里
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;
我第一次使用带有 EF 的 .NET Core 开发一个 Web 应用程序,但我对此有点坚持。请建议我如何在这里处理验证。我在这里并不是特别需要显示验证消息的地方,而是一种通知用户输入正确数字的方法。感谢所有帮助
****编辑****
我看到类似的错误
当我输入的数量少于或多于可用数量时,它没有做任何事情,在 devtools 中我看到了屏幕截图中的错误
Uncaught SyntaxError: Function statements require a function name
在按下“立即购买”按钮之前,URL 类似于 https://localhost:44330/Inventories/Index/460
在我按下 https://localhost:44330/Inventories/Index/460#
之后的任何形式
我无法解决更多问题,有点卡在这里
【问题讨论】:
很难判断发生了什么,因为您只发布了部分视图。你能显示一个获取操作和完整视图,包括模型吗? @Serge 我添加了所有详细信息,如果我遗漏了什么,请告诉我。我有点卡在这里。非常感谢任何帮助 @Serge 订单创建和所有工作.. 它只是当用户输入 quantityReq > intData.QuantityAvailable 我不知道如何显示验证错误 @Serge 我输入了所有的代码,如果你有机会请你帮我解决这个问题。我有点卡住了 由于您的应用程序将使用分页,它使事情变得更加复杂。您将不得不使用一些 javascript 和 ajax 进行验证。您准备好了吗?或者您更愿意从项目中删除分页? 【参考方案1】:试试这个。由于它使用的是 ajax,我删除了一个表单和一个提交按钮
@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" />
</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="#" class="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");
onBuyNow(id);
));
function onBuyNow(id)
$("#errorMessage" + id).val("");
var quantityReq = $("#quantityReq"+id).val();
var customerId = $("#customer"+id).val();
var data =
customerId: customerId,
quantityReq: quantityReq,
inventoryId: id
;
$.ajax(
url: '@Url.Action("OrderItem", "Inventories")',
dataType: 'json',
type: 'POST',
data: data,
success: function (result)
if (result.status !== "Ok")
$("#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>
动作
public async Task<ActionResult> 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 Ok( new status = "NotAvailable", inventoryId=inventoryId, available = intData.QuantityAvailable );
return Ok(new status="Ok" );
并且布局的正文部分的底部应该有
<script src="~/lib/jquery/dist/jquery.min.js"></script>
@await RenderSectionAsync("Scripts", required: false)
【讨论】:
非常感谢您抽出宝贵的时间来获取此信息。我正在尝试了解该调用的工作原理,我已在索引页面的新添加脚本上启用了断点我看到一个问题` $.ajax( url: '@Url.Action("OrderItem", "Inventories")',`函数在 Inedx 页面加载时被调用,当点击立即购买链接时没有任何反应。我在浏览器中看到像Uncaught SyntaxError: Function statements require a function name
. 你认为我遗漏了什么吗,它应该在页面加载时调用$.ajax(url: '@Url.Action("OrderItem", "Inventories")',
你必须在你的项目中安装 javascript 和 jquery。您可以为此使用 libman。谷歌这个名字。并检查开发人员工具 => 浏览器中的控制台是否有错误,如果按钮单击仍然不起作用
我尽了最大努力,但仍然遇到同样的问题Uncaught SyntaxError: Function statements require a function name
我用我所看到的细节更新了问题
我试图在我的控制器上添加断点以查看从“立即购买”按钮调用的操作 OrderItem
,但看起来根本没有调用该操作
@user81642 我期待它。转到 Visual Studio 中的 javascript 代码并很好地检查语法。特别是检查刹车和功能名称。那里只是语法错误。 javascrit 代码屏幕底部有一个复选标记。这个复选标记应该是绿色的。以上是关于用户输入的服务器端验证的主要内容,如果未能解决你的问题,请参考以下文章