Удаление бритвенных страниц с помощью AJAX - PullRequest
4 голосов
/ 13 марта 2020

Я пытаюсь выяснить, используя AJAX с Razor Pages.

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

Пока что я сосредоточился на вариациях чего-то вроде этого:

$.post('/?handler=Delete', 5, function (x) {
    alert(x);
});

И тогда моя модель страницы выглядит так:

public void OnPostDelete(int id)
{

}

Я попробовал варианты этого, но пока мой код C# не вызывается.

Вопросы:

  • Может кто-нибудь показать мне, что мне не хватает?
  • Кто-нибудь может предложить несколько хороших ссылок для этого? (Мне нужно выполнить и другие задачи AJAX.)
  • Некоторые примеры, которые я обнаружил, имели специальную обработку, связанную с токенами против подделки. Нужно ли мне также это кодировать?

ОБНОВЛЕНИЕ:

Итак, я работал с этим, и вот что у меня сейчас:

$.ajax({
    url: '?handler=Delete',
    data: {
        id: $(this).data('id')
    }
})
.fail(function (e) {
    // Error
    alert(e.responseText); // Way too much info
})
.done(function () {
    // Success
})
.always(function () {
    // Always
});

И мой обработчик:

public void OnGetDelete(int id)
{

}

Это фактически вызывает мой обработчик, и я наконец получил его для передачи аргумента id.

Так как у меня есть щедрость, вот что я хотел бы видеть в ответе:

  1. Если я установлю вызов AJAX для использования POST и переименую мой обработчик в OnPostDelete(), обработчик не будет вызван. Как бы я сделал пост?
  2. Любые другие предложения или критику с кодом выше? Я знаю, что есть много способов сделать это. Я просто ищу самый простой способ и пытаюсь его уточнить.

Ответы [ 4 ]

2 голосов
/ 13 марта 2020

Вы можете передать F12 для проверки запроса на вкладке Сеть, вы можете увидеть ошибку 400 неверных запросов.

Страницы Razor предназначены для автоматической защиты от подделки межсайтовых запросов (CSRF / XSRF ) атаки. Вам не нужно писать дополнительный код. Создание и проверка токенов антиподделения автоматически включается в Razor Pages. В этом случае запрос не выполняется, на странице отсутствует AntiForgeryToken.

По этому вопросу вы можете добавить явно, используя @Html.AntiForgeryToken() Чтобы добавить AntiForgeryToken, мы можем использовать любой из подходов. Оба подхода добавляют тип ввода, скрытый с именем __ RequestVerificationToken . Запрос Ajax должен отправить токен защиты от подделки в заголовке запроса на сервер. Таким образом, измененный запрос Ajax выглядит следующим образом:

@Html.AntiForgeryToken()

@section Scripts
{
<script>

    $.ajax({
        type: "POST",
        url: "/?handler=Delete&id="+5,
        beforeSend: function (xhr) {
            xhr.setRequestHeader("XSRF-TOKEN",
                $('input:hidden[name="__RequestVerificationToken"]').val());
        },
        success: function (x) {
            alert(x);
        },
        failure: function (response) {
            alert(response);
        }
    });
</script>

}

Поскольку сценарий отправляет токен в заголовке с именем X-CSRF-TOKEN, настройте антивирусную службу для поиска заголовок X-CSRF-TOKEN:

public void ConfigureServices(IServiceCollection services)
{
        services.AddRazorPages();
        services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}

Ссылка: https://www.talkingdotnet.com/handle-ajax-requests-in-asp-net-core-razor-pages/

1 голос
/ 13 марта 2020

Вот как мне нравится это делать:

Настройка вашего Javascript

//If you're returning a object, configure it
var yourObject = {
    field1: "value1",
    field2: "value2"
};

//setup ajax
$.ajax({
    data: yourObject,
    type: "POST",
    url: "urltoyourhandler/delete" //you can add other paramters here as well by doing ?parm=value
    success: function(data){
      //do success stuff here
      //based off my handler code below:
      if(data.success){
          console.log("Success!");
      }
      else{
          console.log("Failed for some reason!");
      }
    }
    error: function(){
        //do error stuff here
       //gets called if there is a issue contacting the URL or if there is a server error like 500
    }
});

Настройка вашего обработчика. Для моих операций CRUD мне нравится делать CRUD-контроллер для обработки всего, что

[BindProperty]
public YourClass Name { get; set; }

//set handler to only accept POST and set a URL for it. URL should be to the same folder you're in
//the 'delete' in route doesn't have to match the function name but it's less confusing if it does
[HttpPost, Route("RouteToThisHandler/delete)]
public async Task<IActionResult> Delete()
{
    //verify data and the do something with it
    //I like returning a JsonResult. Add whatever data you want. I like returning success 
    //with true or false and some other data if needed
    return new JsonResult(new { success: true, importantInfo: "This is important" });
}

Ajax имеет больше параметров конфигурации, чтобы дать вам больше информации о любых ошибках сервера, которые происходят

Что касается Токен защиты от подделки, Microsoft говорит:

Промежуточное программное обеспечение защиты от подделки добавляется в контейнер внедрения зависимости, когда в Startup.ConfigureServices вызывается один из следующих API:

  • Добавить Mvc
  • MapRazorPages
  • MapControllerRoute
  • MapBlazorHub

Вот ссылка Microsoft на токен защиты от подделки: https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-3.1

0 голосов
/ 23 марта 2020

Я исследовал несколько вещей: что происходит, когда вы передаете строку из AJAX вместо целого числа и как различные маршруты влияют на вызов (см. Интересную заметку ниже, если у вас есть время) Но в основном все, что я нашел в том, что Razor Pages довольно просты, и все, кажется, просто работает. Как я уже говорил, даже передавая строку, в которой целочисленный тип id все еще попадает в метод-обработчик (он просто дал мне default(int))

, я создал этот репозиторий только для исследования: https://github.com/EntityAdam/RazorPageHandlers

Основным блокировщиком, как указал @Yan, является токен Anti-Forgery. Это действительно единственное, что заставило обработчик не достичь точки останова. Как было предложено, проверьте вкладку сети на наличие неудачных запросов или консоль для кода bum JavaScript.

Из своего фрагмента, чтобы изменить его на OnPostDelete, вам нужно будет использовать тип POST в AJAX вызов И включает токен против подделки.

$.ajax({
    type: 'POST',
    headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
    url: '?handler=Delete',
    data: {
        id: $(this).data('id')
    }
})
.fail(function (e) {
    // Error
    alert(e.responseText); // Way too much info
})
.done(function () {
    // Success
})
.always(function () {
    // Always
});

Еще один топи c, который я не видел обсуждаемым, - откуда этот токен? Он генерируется Razor автоматически, когда есть элемент <form>. Если у вас нет элемента <form>, вы можете генерировать токены, когда они вам нужны, ознакомьтесь с блоком @functions {} в этой статье MSDN . Есть также сценарий ios, где CSRF бесполезен или не требуется, и вы также можете отключить защиту от подделки, если она вам не нужна (это совершенно другое обсуждение).

Моя критика подхода мнения, так что принимайте их или оставляйте.

  • Не используйте jQuery, если вы можете избежать этого, исходя из предпосылки, что улучшения JavaScript возможно устарели jQuery. Используйте простой ванильный код JS.
  • Ajax также показывает его возраст. Если вам нужна только поддержка современных браузеров, рассмотрите Fetch API
  • Не пишите JS вообще! Blazor новый и блестящий. Все еще есть некоторые проблемы с ростом, но я бы предпочел, чтобы моя боль была в C#, чем в JavaScript =)

Интересная вещь, с которой я столкнулся ..

Для В этой демонстрации я использовал следующую директиву @page

@page "{id?}"

В части HTML таких форм, как:

<form method="post" asp-page-handler="Delete">
    <input type="hidden" name="id" value="1" />
    <button class="btn btn-danger">Delete</button>
</form>

Я использую помощник по тегам asp-page-handler чтобы помочь в создании правильного URL. Для обработчика Create с этой директивой @page помощник по тегам получает цель формы /?handler=Create

Если вы замените эту директиву @page на @page "{handler?}/{id:int?}", помощник по тегам определит маршрут который сейчас /Delete. Но угадайте что? Вызовы AJAX работают с любой директивой @page, хотя URL-адрес в AJAX жестко задан в ?handler=Delete'

0 голосов
/ 13 марта 2020

Два предложения:

1 - добавить путь к странице перед URL-адресом. (Я не уверен, упоминается ли это в ваших словах).

$.post('/{page_path}/?handler=Delete', 5, function (x) {
    alert(x);
});

2- Следуйте правилу карты маршрута. Например, в вашей функции есть «id». Возможно, страница настроена как @page "{id: int}". Таким образом, URL должен быть что-то вроде

$.post('/{page_path}/{id}/?handler=Delete', 5, function (x) {
    alert(x);
 });
...