Как сделать маршрутизацию с параметрами в ASP. NET Core 3.1 - PullRequest
3 голосов
/ 27 апреля 2020

В ASP. NET Ядро 3.1, когда я указываю маршрут в контроллере, должно иметь вид

[Route("/[area]/[controller]/[action]/{id}")]

, но когда оно похоже на

[Route("/[area]/[controller]/[action]?id={id}")]

, оно возвращает ошибка 500.

Я хочу показать TableData из JS в маршруте

 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>
}

порядок. 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%"
            }
        ]
    });
}

Результаты

enter image description here

enter image description here

Спасибо!

Ответы [ 3 ]

1 голос
/ 28 апреля 2020

Ниже приведена рабочая демонстрация с данными тестирования, см. Ее.

Javascript код

$(document).ready(function () {

    var url = window.location.search;

    //console.log(url);
    var status = GetURLParameter("status");

    switch (status) {
        case "inprocess": loadDataTable("GetOrderList?status=inprocess"); break;
        case "pending": loadDataTable("GetOrderList?status=pending"); break;
        case "completed": loadDataTable("GetOrderList?status=completed"); break;
        case "rejected": loadDataTable("GetOrderList?status=rejected"); break;
        case "approved": loadDataTable("GetOrderList?status=approved"); break;
        default: loadDataTable("GetOrderList?status=all");
    }
});

function GetURLParameter(sParam) {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++) {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam) {
            return sParameterName[1];
        }
    }
}


function loadDataTable(url) {
    //console.log(url);
    $('#tblData').DataTable({
        "ajax": {
            "url": "/Admin/Order/" + url
        },
        "columns": [
            {
                "data": "id",
                "render": function (data) {
                    console.log(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">${data}</i>
                                </a>
                            </div>
                            `;
                },
                "width": "15%"
            },
            { "data": "applicationUser.Name", "width": "15%" },
            { "data": "applicationUser.phoneNumber", "width": "15%" },
            { "data": "applicationUser.email", "width": "15%" },
            { "data": "orderStatus", "width": "15%" },
            { "data": "orderTotal", "width": "15%" }
        ]
    });
}

Действия контроллера

[Area("Admin")]
[Route("Admin/Order/")]
public class OrderController : Controller
{
    private readonly List<AppUserOrder> appUserOrders;
    public OrderController()
    {
        appUserOrders = new List<AppUserOrder>
        {
            new AppUserOrder
            {
                Id = 1,
                ApplicationUserId = Guid.NewGuid().ToString(),
                ApplicationUser =new ApplicationUser
                {
                    UserName = "Jesus",
                    Email = "Jesus email here",
                    PhoneNumber = "673533658"
                },
                OrderStatus = "pending",
                OrderTotal = 25
            },
            new AppUserOrder
            {
                Id = 2,
                ApplicationUserId = Guid.NewGuid().ToString(),
                ApplicationUser =new ApplicationUser
                {
                    UserName = "Ray",
                    Email = "Ray email here",
                    PhoneNumber = "673533659"
                },
                OrderStatus = "completed",
                OrderTotal = 39
            },
            new AppUserOrder
            {
                Id = 3,
                ApplicationUserId = Guid.NewGuid().ToString(),
                ApplicationUser =new ApplicationUser
                {
                    UserName = "Wall",
                    Email = "Wall email here",
                    PhoneNumber = "673533656"
                },
                OrderStatus = "inprocess",
                OrderTotal = 128
            },
            new AppUserOrder
            {
                Id = 4,
                ApplicationUserId = Guid.NewGuid().ToString(),
                ApplicationUser =new ApplicationUser
                {
                    UserName = "Jack",
                    Email = "Jack email here",
                    PhoneNumber = "673533655"
                },
                OrderStatus = "rejected",
                OrderTotal = 206
            },
            new AppUserOrder
            {
                Id = 5,
                ApplicationUserId = Guid.NewGuid().ToString(),
                ApplicationUser =new ApplicationUser
                {
                    UserName = "Terry",
                    Email = "Terry email here",
                    PhoneNumber = "673533653"
                },
                OrderStatus = "approved",
                OrderTotal = 102
            }
        };


    }
    public IActionResult Index(string status)
    {
        return View();
    }

    [Route("GetOrderList")]
    [HttpGet]
    public IActionResult GetOrderList(string status)
    {
        List<AppUserOrder> res = appUserOrders;

        if (status!="all")
        {
            res = appUserOrders.AsQueryable().Where(a => a.OrderStatus == status).ToList();
        }

        return new JsonResult(new { data = res });
    }
}

Классы моделей

public class AppUserOrder
{
    public int Id { get; set; }
    public string ApplicationUserId { get; set; }
    public ApplicationUser ApplicationUser { get; set; }
    public int OrderTotal { get; set; }
    public string OrderStatus { get; set; }
}

public class ApplicationUser
{
    [JsonPropertyName("Name")]
    public string UserName { get; set; }
    public string Email { get; set; }
    public string PhoneNumber { get; set; }
}

Данные тестирования

{"data":[{"id":1,"applicationUserId":"e6aaa9ac-2bd7-4aa7-8f74-e6bce58236ad","applicationUser":{"Name":"Jesus","email":"Jesus email here","phoneNumber":"673533658"},"orderTotal":25,"orderStatus":"pending"},{"id":2,"applicationUserId":"85eb90a0-44e9-4266-b6d0-3f72fc122c24","applicationUser":{"Name":"Ray","email":"Ray email here","phoneNumber":"673533659"},"orderTotal":39,"orderStatus":"completed"},{"id":3,"applicationUserId":"c1031399-4ebe-4d64-addf-4852f19e30f7","applicationUser":{"Name":"Wall","email":"Wall email here","phoneNumber":"673533656"},"orderTotal":128,"orderStatus":"inprocess"},{"id":4,"applicationUserId":"02ff9515-5633-4981-ab06-2b1f9b01c375","applicationUser":{"Name":"Jack","email":"Jack email here","phoneNumber":"673533655"},"orderTotal":206,"orderStatus":"rejected"},{"id":5,"applicationUserId":"3e524698-f2b5-488b-bffb-4287d3447da5","applicationUser":{"Name":"Terry","email":"Terry email here","phoneNumber":"673533653"},"orderTotal":102,"orderStatus":"approved"}]}

Результат теста

enter image description here

1 голос
/ 28 апреля 2020

Параметры маршрута отличаются от параметров запроса.

, когда URL-адрес похож на /some/action/and/property/id, то есть параметры маршрута и анализируются с помощью /, а ключи задаются на основе положения параметра. Параметры маршрута могут быть либо stati c (/ some / action), либо могут включать значения Dynami c (/some/action/-199IDID .).

Когда вы работаете с форматом ?key=value&key2=value2, Вы имеете дело с параметрами запроса. Поскольку эти параметры не являются параметрами маршрута, поскольку они не зависят от текущего маршрута, вам не нужно украшать ваше действие маршрутизацией и просто использовать параметры в качестве входных данных для вашей функции:

GET: /index?status=1

[Route("[action]")]
public IActionResult Index(string status){
    // "status" is bound from query string ?status=1.
    // "index" is bound from route [action]
}
1 голос
/ 27 апреля 2020

Проверьте Microsoft Routing Documentation

Шаблон маршрута выглядит как путь URI, но он может иметь значения заполнителей, обозначенные фигурными скобками

Таким образом, [Route("/[area]/[controller]/[action]?id={id}")] не является допустимым маршрутом, следовательно, ошибка 500

Если вы хотите передать что-то в качестве параметра запроса, используйте атрибут FromQuery.

Вы можете также есть несколько методов Get в одном контроллере с разными маршрутами

    [Route("Index")]
    [HttpGet]
    public IActionResult Index()
    {
        return View();
    }

Если вы отправляете параметр запроса в индекс, добавьте его также в параметры

    [Route("Index")]
    [HttpGet]
    public IActionResult Index(string status)
    {
        return View();
    }

Кстати У вас также есть опечатка:

loadDataTable("GetOrderList/status=pending");
...