Ниже вызов Ajax не вызывает метод Non-контроллера (Index) в .NET core 6.
$.ajax({
type: 'POST',
contentType: false,
processData: false,
url: form.action,
data: formData,
success: () => {
},
error: () => {
}});
HTML:
<form method = "POST" enctype = "multipart/form-data">
@Html.AntiForgeryToken()
<div>
--------
----
--
</div>
<div class = "btns">
<button class = "fill reset-button" type = "button">@Html.PropertyFor(model => model.ResetButtonText)</button>
<button class = "fill send-button" type = "button" this.disabled = "true">@Html.PropertyFor(model => model.SendButtonText)</button>
</div>
<br />
<div class = "se">
<div class = "alert alert-info" style = "display:none">Sending...</div>
<div class = "alert alert-danger" style = "display:none">There was an issue with the submitted data. Please correct any errors and resubmit.</div>
<div class = "alert alert-success" style = "display: none">Your message was sent successfully.</div>
</div>
</form>
Метод:
[HttpPost]
[ValidateAntiForgeryToken]
public IViewComponentResult Index(Block currentContent, ViewModel viewModel)
{
//code
}
Жестко закодировал URL-адрес, но он не вызывает метод Index. Вызов Ajax должен вызывать метод Index, который не является частью папки Controllers.
Где этот метод Index()
, почему вы ожидаете, что для него будет публичная конечная точка? Кроме того, как данные формы будут соответствовать аргументам метода Index()
?
@YuningDuan, наш проект использует MVC. Я проверил инструменты разработчика, все соответствующие данные передаются по запросу. Информации об ошибке нет. Я вызываю метод, находящийся за пределами контроллеров.
@TedNyberg, в рамках обновления Optimizely мы перенесли некоторые контроллеры в компоненты. Теперь я вызываю метод, который является частью одного из компонентов. Данные передаются из вызова Ajax.
Является ли предоставленный вами метод Index классом, наследуемым от контроллера? Или он унаследован от класса ViewComponent?
он унаследован от класса ViewComponent @YuningDuan
В .NET Core доступ к ViewComponent не осуществляется через традиционную маршрутизацию контроллера. Обычно он вызывается с помощью метода @Component.InvokeAsync в компонентах представления или представления страницы.
Если вы хотите отправить соответствующую конечную точку URL-адреса с помощью ajax, вы можете отправить метод, унаследованный от контроллера, вызвать в нем компонент представления, передать currentContent
и viewModel
и вернуть результат компонента представления. Вот пример для справки:
Сначала я настроил соответствующий метод в контроллере, чтобы он соответствовал URL-адресу и данным конечной точки ajax, а затем вызвал созданный мною компонент с именем home1
:
Homecontroller:
public class HomeController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult InvokeHome1Component(Block currentContent, ViewModel viewModel)
{
var result = ViewComponent("Home1", new { currentContent, viewModel });
return result;
}
}
Home1ViewComponent:
public class Home1ViewComponent : ViewComponent
{
[HttpPost]
[ValidateAntiForgeryToken]
public IViewComponentResult Invoke(Block currentContent, ViewModel viewModel)
{
return View(viewModel);
}
}
Я настроил соответствующее представление компонента по пути Views\Home\Components\Home1\Default.cshtml:
@model ViewModel
<div>
<h1>@Model.ResetButtonText</h1>
<h1>@Model.SendButtonText</h1>
</div>
Ajax отправляет соответствующую конечную точку URL. И я настроил содержимое страницы обновления в обратном вызове успеха и представил его в <div id = "viewComponentContainer"></div>
:
@model ViewModel
<form method = "POST" enctype = "multipart/form-data" >
@Html.AntiForgeryToken()
<div>
</div>
<div class = "btns">
<button class = "fill reset-button" type = "button">@Html.DisplayFor(model => model.ResetButtonText)</button>
<button class = "fill send-button" type = "submit">@Html.DisplayFor(model => model.SendButtonText)</button>
</div>
<br />
<div class = "se">
<div class = "alert alert-info" style = "display:none">Sending...</div>
<div class = "alert alert-danger" style = "display:none">There was an issue with the submitted data. Please correct any errors and resubmit.</div>
<div class = "alert alert-success" style = "display: none">Your message was sent successfully.</div>
</div>
</form>
<div id = "viewComponentContainer"></div>
@section scripts {
<script>
$(document).ready(function () {
$('form').on('submit', function (event) {
event.preventDefault();
var form = this;
var formData = new FormData(form);
formData.append('currentContent', 'exampleContent');
formData.append('viewModel.ResetButtonText', 'Reset');
formData.append('viewModel.SendButtonText', 'Send');
$.ajax({
type: 'POST',
contentType: false,
processData: false,
url: '/Home/InvokeHome1Component',
data: formData,
success: function (response) {
$('#viewComponentContainer').html(response);
$('.alert-info').hide();
$('.alert-success').show();
},
error: function () {
$('.alert-info').hide();
$('.alert-danger').show();
},
beforeSend: function () {
$('.alert-info').show();
}
});
});
});
</script>
}
Когда я нажимаю кнопку отправки, данные сначала будут отправлены в мой метод контроллера:
а затем перешел к моему компоненту представления:
Наконец, на мой взгляд, обновление компонента завершено и загружено:
Обновлять:
После моего теста, когда имя параметра в модели совпадает с именем параметра модели, полученным в методе, данные не могут быть получены в контроллере, например:
public class Block
{
public int? Id { get; set; }
public string? currentContent { get; set; }
}
Это приведет к сбою привязки модели. Поэтому, чтобы избежать этой ошибки, вам необходимо избегать встречи с одним и тем же именем, например, меняя имя параметра в модели:
public class Block
{
public int? Id { get; set; }
public string? Content { get; set; }
}
public class ViewModel
{
public string? ResetButtonText { get; set; }
public string? SendButtonText { get; set; }
}
аякс:
formData.append('Content', 'exampleContent');
formData.append('viewModel.ResetButtonText', 'Reset');
formData.append('viewModel.SendButtonText', 'Send');
При повторной передаче данных
В Controller currentContent имеет значение null, но в Component он содержит данные. Нужно ли нам что-нибудь назначать перед вызовом AJAX? Я мог видеть приведенный ниже код для передачи currentContent(BlockContent) formData.append('currentContent', 'exampleContent') но не совсем ясно, какие данные нужно передать здесь.
Разве мы не можем использовать один из них — Контроллер или Компонент — для достижения всего, что требуется. Целесообразно ли использовать их оба для простых запросов GET, POST.
Я обновил причину, по которой метод контроллера не может получить данные в части обновления. Вы можете проверить, есть ли та же причина. `Разве мы не можем использовать ни один из них, контроллер или компонент, для достижения всего, что требуется`. Можете ли вы описать, чего вы хотите достичь?
Достаточно ли одного контроллера для обработки запросов GET и POST или также необходим компонент представления? В качестве альтернативы, может ли компонент представления самостоятельно обрабатывать запросы GET и POST или есть конкретная причина для использования как контроллеров, так и компонентов представления?
В вашем проекте используется ядро asp.net razorpage или mvc? Проверили ли вы в инструментах разработчика, успешно ли ajax отправил запрос и связанные с ним данные? Есть ли какая-либо соответствующая информация об ошибках в инструментах разработчика? Упомянутый вами метод в контроллере находится в отдельной папке или на странице бритвы?