c# - 如何在 ASP.NET Core 3.1 中使用参数进行路由
问题描述
在 ASP.NET Core 3.1 中,当我在控制器中指定路由时,必须是那种
[Route("/[area]/[controller]/[action]/{id}")]
但是当它像
[Route("/[area]/[controller]/[action]?id={id}")]
它返回错误 500。
我想在路由中显示来自 JS 的 TableData
Admin/Order/Index?status={status}
但是,在控制器中,HttpGet 是操作GetOrderList
,因此数据被发送到
Admin/Order/GetOrderList?status={status}
我怎样才能正确配置路由?
控制器:
[Area("Admin")]
[ApiController]
[Route("Admin/Order/")]
[Authorize]
public class OrderController : Controller
{
#region Properties
private readonly IUnitOfWork _unitOfWork;
private Claim _claim
{
get
{
ClaimsIdentity claimsIdentity = (ClaimsIdentity)User.Identity;
return claimsIdentity.FindFirst(ClaimTypes.NameIdentifier);
}
set { }
}
#endregion
public OrderController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
[Route("Index")]
public IActionResult Index()
{
return View();
}
#region API CALLS
[Route("GetOrderList")]
[HttpGet]
public IActionResult GetOrderList(string status)
{
IEnumerable<OrderHeader> orderHeaderList;
// Repetimos codigo del switch, para que la recogida de datos sea más eficiente.
// Si hicieramos switch al final, y aplicamos filtro al IEnumerable<T>, estamos leyendo
// Todos los datos, y despues aplicamos filtro
// Mientras que si aplicamos el filtro en el GetAll() hacemos uso del IQueryable<T> que
// Aplica el filtro en la base de datos, y carga en memoria lo necesario
if(User.IsInRole(SD.Role_Admin) || User.IsInRole(SD.Role_Employee))
{
// Si es admin, puede gestionar todas las transacciones
switch (status)
{
case "pending":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.PaymentStatus == SD.PaymentStatusDelayedPayment,
includeProperties: "ApplicationUser");
break;
case "inprocess":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.OrderStatus == SD.StatusApproved ||
item.OrderStatus == SD.StatusInProcess ||
item.OrderStatus == SD.StatusPending,
includeProperties: "ApplicationUser");
break;
case "completed":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.OrderStatus == SD.StatusShipped,
includeProperties: "ApplicationUser");
break;
case "rejected":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.OrderStatus == SD.StatusCancelled ||
item.OrderStatus == SD.StatusRefunded,
includeProperties: "ApplicationUser");
break;
case "approved":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.OrderStatus == SD.PaymentStatusApproved ||
item.OrderStatus == SD.StatusApproved,
includeProperties: "ApplicationUser");
break;
default:
orderHeaderList = _unitOfWork.OrderHeader.GetAll(includeProperties: "ApplicationUser");
break;
};
}
else
{
// Si es trabajador, solo puede acceder a las suyas
switch (status)
{
case "pending":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.ApplicationUserId == _claim.Value &&
(item.PaymentStatus == SD.PaymentStatusDelayedPayment), includeProperties: "ApplicationUser");
break;
case "approved":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.ApplicationUserId == _claim.Value &&
(item.OrderStatus == SD.PaymentStatusApproved ||
item.OrderStatus == SD.StatusApproved), includeProperties: "ApplicationUser");
break;
case "inprocess":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.ApplicationUserId == _claim.Value &&
(item.OrderStatus == SD.StatusApproved ||
item.OrderStatus == SD.StatusInProcess ||
item.OrderStatus == SD.StatusPending), includeProperties: "ApplicationUser");
break;
case "completed":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.ApplicationUserId == _claim.Value &&
(item.OrderStatus == SD.StatusShipped), includeProperties: "ApplicationUser");
break;
case "rejected":
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.ApplicationUserId == _claim.Value &&
(item.OrderStatus == SD.StatusCancelled ||
item.OrderStatus == SD.StatusRefunded), includeProperties: "ApplicationUser");
break;
default:
orderHeaderList = _unitOfWork.OrderHeader.GetAll(item => item.ApplicationUserId == _claim.Value, includeProperties: "ApplicationUser");
break;
};
}
return Json(new { data = orderHeaderList });
}
#endregion
}
索引视图:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
var status = Context.Request.Query["status"];
var approved = "text-primary";
var pending = "text-primary";
var all = "text-primary";
var inprocess = "text-primary";
var completed = "text-primary";
var rejected = "text-primary";
switch (status)
{
case "pending":
pending = "active text-white";
break;
case "approved":
approved = "active text-white";
break;
case "inprocess":
inprocess = "active text-white";
break;
case "completed":
completed = "active text-white";
break;
case "rejected":
rejected = "active text-white";
break;
default:
all = "active text-white";
break;
};
}
<br />
<div class="border p-3">
<div class=" d-flex justify-content-between mb-3">
<div class="p-2">
<h2 class="text-primary">Order's List </h2>
</div>
<div class="p-2">
<ul class="list-group list-group-horizontal-sm">
<a style="text-decoration:none;" asp-controller="Order" asp-action="Index" asp-route-status="inprocess">
<li class="list-group-item @inprocess"> In Process</li>
</a>
<a style="text-decoration:none;" asp-controller="Order" asp-action="Index" asp-route-status="pending">
<li class="list-group-item @pending">Pending</li>
</a>
<a style="text-decoration:none;" asp-controller="Order" asp-action="Index" asp-route-status="completed">
<li class="list-group-item @completed">Completed</li>
</a>
<a style="text-decoration:none;" asp-controller="Order" asp-action="Index" asp-route-status="approved">
<li class="list-group-item @approved">Approved</li>
</a>
<a style="text-decoration:none;" asp-controller="Order" asp-action="Index" asp-route-status="rejected">
<li class="list-group-item @rejected">Rejected</li>
</a>
<a style="text-decoration:none;" asp-controller="Order" asp-action="Index" asp-route-status="all">
<li class="list-group-item @all">All</li>
</a>
</ul>
</div>
</div>
<br /><br />
<table id="tblData" class="table table-striped table-bordered" style="width:100%">
<thead class="thead-dark">
<tr class="table-info">
<th>Id</th>
<th>Name</th>
<th>Phone number</th>
<th>Email</th>
<th>Order status</th>
<th>Amount</th>
</tr>
</thead>
</table>
</div>
@section Scripts {
<script src ="~/js/order.js"></script>
}
order.js
var dataTable;
$(document).ready(function () {
var url = window.location.search;
if (url.includes("inprocess")) {
loadDataTable("GetOrderList?status=inprocess");
} else {
if (url.includes("pending")) {
loadDataTable("GetOrderList/status=pending");
} else {
if (url.includes("completed")) {
loadDataTable("GetOrderList?status=completed");
} else {
if (url.includes("rejected")) {
loadDataTable("GetOrderList?status=rejected");
} else {
loadDataTable("GetOrderList?status=all")
}
}
}
}
});
function loadDataTable(url) {
dataTable = $('#tblData').DataTable({
"ajax": {
"url": "/Admin/Order/" + url
},
"columns": [
{ "data": "id", "width": "15%" },
{ "data": "name", "width": "15%" },
{ "data": "phoneNumber", "width": "15%" },
{ "data": "applicationUser.email", "width": "15%" },
{ "data": "orderStatus", "width": "15%" },
{ "data": "orderTotal", "width": "15%" },
{
"data": "id",
"render": function (data) {
return `
<div class="row text-center">
<a href="/Admin/Order/Details/${data}" class="btn btn-success text-white" style="cursor:pointer">
<i class="fas fa-edit"></i>
</a>
</div>
`;
}, "width": "10%"
}
]
});
}
结果
谢谢!
解决方案
路由模板看起来类似于 URI 路径,但它可以有占位符值,用花括号表示
所以这[Route("/[area]/[controller]/[action]?id={id}")]
不是一个有效的路线,因此错误 500
如果您想将某些内容作为 Query 参数传递,请使用该FromQuery
属性。
您还可以在具有不同路由的同一控制器中拥有多个 Get 方法
[Route("Index")]
[HttpGet]
public IActionResult Index()
{
return View();
}
如果要向索引发送查询参数,请将其也添加到参数中
[Route("Index")]
[HttpGet]
public IActionResult Index(string status)
{
return View();
}
顺便说一句,你还有一个错字:
loadDataTable("GetOrderList/status=pending");
推荐阅读
- .net - TokenValidationParameters 类的属性有什么意义
- sql - 有没有更好的方法从 Oracle 表中检索随机行?
- python - 如何使用 StringIO 从内存中以 CSV 格式发送数据帧
- python - 我正在尝试使用 Python 库 pyral 在 CA Rally 中上传测试用例,测试用例已成功上传,但无法为测试用例设置所有者
- javascript - 无法在 Angular 7 中触发 SVG 上的鼠标事件
- java - 在最近的 android 更新后无法从 Uri 创建文件
- rxjs - 如何从课堂上启用可观察的
- math - 在不使用任何边两次的情况下,按特定顺序在几个节点之间的最短路径是什么?
- javascript - 如果要访问的 id 存储在变量中,如何访问元素
- java - 无法在 Android Studio 中运行 Scratch 文件