Фрагмент JavaScript — Edit(id) — извлекает с сервера правильный HTML для редактирования сообщения и встраивает его на страницу.
Другой фрагмент javascript — Save(id) — отправляет AJAX POST обратно на сервер и вставляет результат. обратно на страницу.
Согласно правилам AntiForgery Razor Pages, POST вызывает ошибку 404, поскольку отсутствует правильный токен. Поскольку я не использую , встроенная система защиты от подделки не срабатывает автоматически и не предоставляет токен.
И поскольку у меня есть такая возможность Теоретически параллельно редактируя несколько сообщений, я не уверен, как правильно реализовать поле @Html.AntiForgeryToken(). Должен ли я генерировать токен для каждого сообщения, а затем каким-то образом собирать его и отправлять вместе с моим POST, или...?
Мне интересно, есть ли правильный способ обработки этот сценарий, который учитывает AntiForgery, или мне просто придется смириться с этим и строить вокруг него? Я могу легко обойти эту проблему с помощью [IgnoreAntiforgeryToken], но это, очевидно, имеет свои последствия.
На данный момент MessageManager.Messages — это всего лишь статический список
View.cshtml
Код: Выделить всё
@foreach (var item in Model.Messages) {
@item.Type:
@{
var result = Markdown.ToHtml(item.Message, pipeline);
@Html.Raw(result)
}
[url=#]✏[/url]
[url=#]❌[/url]
}
@section Scripts {
function Edit(messageId) {
$.get(
"/Messages/_EditMessage?messageId=" + messageId,
function (str) {
$('#message_' + messageId).html(str);
}
);
}
function Save(messageId) {
$.post(
"/Messages/_EditMessage?messageId=" + messageId,
{ NewMessage: $('#NewMessage_' + messageId).val() },
function (str) {
$('#message_' + messageId).html(str);
}
);
}
}
_EditMessage.cshtml
Код: Выделить всё
@if (Model.Edit) {
@Model.Message.Type
@Model.Message.Message
Save
}
else {
var result = Markdown.ToHtml(Model.Message.Message, pipeline);
@Model.Message.Type:
@Html.Raw(result)
}
_EditMessage.cshtml.cs
Код: Выделить всё
[IgnoreAntiforgeryToken]
public class _EditMessageModel : PageModel
{
public TextMessage Message { get; set; } = null!;
public bool Edit { get; set; }
[BindProperty] public string NewMessage { get; set; } = string.Empty;
public IActionResult OnGet(int messageId) {
var message = MessageManager.Messages.FirstOrDefault(m => m.Id == messageId);
if (message is null)
return NotFound(messageId);
Message = message;
Edit = true;
return Page();
}
public IActionResult OnPost(int messageId) {
var message = MessageManager.Messages.FirstOrDefault(m => m.Id == messageId);
if (message is null)
return NotFound(messageId);
Message = message;
Message.Message = NewMessage;
Edit = false;
return Page();
}
}
Все действительно было так просто.
Добавьте @ Html.AntiForgeryToken() в нижнюю часть страницы просмотра и замените функцию Save() на
Код: Выделить всё
function Save(messageId) {
$.ajax({
type: "POST",
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
url: "/Messages/_EditMessage?messageId=" + messageId,
data: { NewMessage: $('#NewMessage_' + messageId).val() }
}).done(function(response){
$('#message_' + messageId).html(response);
});
}
Подробнее здесь: https://stackoverflow.com/questions/789 ... azor-pages
Мобильная версия