Как я могу гарантировать, что методы контроллера вводятся только в определенной последовательности

Контроллер:

public async Task<IActionResult> Cart()
{
    //some logic
}

public async Task<IActionResult> Payment()
{
    //some logic
}

Корзина.cshtml:

<form method = "post" asp-action = "Payment" asp-controller = "Tech">
    <button></button>
</form>

Я хочу, чтобы пользователи не могли просто набрать MyDomain/MyController/Payment и получить доступ к странице оплаты. Я хочу убедиться, что пользователь нажал кнопку на странице корзины, чтобы ему было разрешено перейти на страницу оплаты. Решение, о котором я подумал, — использовать TempData[], чтобы сохранить имя последней посещенной страницы, а затем проверить, имеет ли словарь значение null или есть ли в нем имя, но я уверен, что должен быть лучший способ.

Прежде всего, вам следует добавить проверку во внешнем интерфейсе, если при отправке запроса на оплату есть какая-либо запись в корзине, в противном случае заблокируйте запрос. Всегда имейте в виду, что этой проверкой можно довольно легко манипулировать во внешнем интерфейсе, поэтому в целях безопасности вам потребуется еще одна проверка в серверной части. Веб-сервисы RESTful не имеют состояния. Поэтому вам необходимо передать корзину на маршрут оплаты или сохранить корзину в базе данных и загрузить ее на маршрут оплаты.

Sebastian S. 18.06.2024 22:50

@СебастьянС. У меня есть внутренний код, который проверяет, есть ли в корзине запись, я просто не включил ее, чтобы вопрос был проще понять, потому что я прошу что-то еще. Также каждая корзина сохраняется в базе данных. Но спасибо за ваше беспокойство.

Alice 19.06.2024 14:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как я могу гарантировать, что методы контроллера вводятся только в конкретная последовательность

Что ж, согласно вашему сценарию и описанию, с этим можно справиться несколькими способами, кроме TempData[]. Также здесь tempData не является идеальным или лучшим способом сделать это, поскольку tempdata не является постоянным.

Идеальными способами можно рассмотреть либо привязку модели, либо использование состояния сеанса. Используя оба способа, сначала мы проверим статус последней посещенной пользователем страницы, и если пользователи перейдут со страницы корзины, мы разрешим им посетить страницу оплаты. В противном случае их можно снова перенаправить на страницу корзины.

Давайте посмотрим на практике, как мы можем этого добиться,

Использование привязки модели:

Это один из простых способов реализовать ваше требование. Мы бы установили статус страницы при загрузке страницы корзины как скрытое значение и проверяли бы значение при загрузке страницы оплаты, если оно истинно или нет, означает, что пользователи посещают страницу напрямую или из корзины.

Давайте реализуем это:

Демо-модель:

public class TransitionModel
{
    public bool FromCart { get; set; }
}

Контроллер:

public class TechController : Controller
{
    public IActionResult Cart()
    {
        var model = new TransitionModel();
        return View(model);
    }

    //[HttpPost]
    public async Task<IActionResult> Payment(TransitionModel model)
    {
        if (model.FromCart)
        {
            
            return View();
        }
        else
        {
            
            return RedirectToAction("Cart");
        }
    }
}

Вид:

@model TransitionModel

<form method = "get" asp-action = "Payment" asp-controller = "Tech">
    <input type = "hidden" asp-for = "FromCart" value = "true" />
    <button type = "submit">Go to Payment</button>
</form>

Примечание. Для загрузки страницы оплаты у вас, вероятно, есть одна страница для загрузки представления, которая является типом GET, а другое действие должно иметь метод с POST, который будет получать запрос на платеж. В обоих действиях вы можете фильтровать значение FromCart. Я проверяю только загрузку, поэтому использовал GET. Вы можете попробовать оба.

Выход:

Промежуточное программное обеспечение с сеансовым подходом:

Чтобы использовать промежуточное программное обеспечение и подход состояния сеанса, прежде всего нам нужна переменная сеанса, в которой мы будем хранить информацию о последней посещенной странице. В этом случае, если последней посещенной страницей является корзина, мы бы разрешили пользователю посещать оплату чего-либо, кроме этого, которое мы бы проигнорировали.

Проверим реализацию:

public class NavigationMiddleware
{
    private readonly RequestDelegate _next;

    public NavigationMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var path = context.Request.Path.Value.ToLower();
        
        if (!path.Contains("/payment") && !path.Contains("/cart"))
        {
           
            await _next(context);
            return;
        }

      
        context.Session.SetString("LastVisitedPage", path);

        await _next(context);
    }
}

Программа.cs:

app.UseSession();
app.UseMiddleware<NavigationMiddleware>();

Примечание. Как видите, мы сохраняем текущую страницу в сеансе и игнорируем пути, которые не являются частью последовательности. Вы можете обратиться к этому официальному документу для получения сведений о промежуточном программном обеспечении и управлении состоянием сеанса.

Я вижу, как работают оба способа. Спасибо, что поделились ими. Я просто ожидал, что Microsoft придумала что-то более простое, например, атрибут метода, который проверяет, поступил ли запрос с определенной страницы. Для Asp.Net имело бы смысл иметь эту функцию.

Alice 19.06.2024 14:58

На данный момент в asp.net нет встроенного метода, атрибута, чтобы вы могли напрямую использовать его, и у нас есть эти варианты для удовлетворения ваших требований.

Md Farid Uddin Kiron 20.06.2024 04:12

Другие вопросы по теме