好的,这是我在这里的第一个问题,所以我会尽量清楚,不要重复别人之前的问题。我确实尝试在发布之前在论坛上搜索,但我发现什么都没有帮助我解决我的问题。如果我错过了一个合适的答案,请轻轻地将此问题略微复制。
所以我的目标是在部分视图中发布表单后向用户发送通知,告诉他是否有效或后端是否有问题。我也希望不重新加载整个视图只是为了显示通知。
我的问题是什么是从后端向UI发送通知而不刷新整个视图的最佳方式。
这是我到目前为止所尝试的以及为什么它不起作用:
首次尝试将数据添加到 ViewData 字典并将其传递给视图。它可以工作但是再次加载整个页面,这是不受欢迎的。
正如我所看到的那样,在返回视图之前重定向到 GET 请求是一个好习惯,我创建了一个重定向到成功方法,然后显示 ViewData 字典,但我发现它不起作用,因为重定向不允许我通过viewdata传递任何内容。
之后我发现我可能会使用 TempData ,因为它通过重定向而不是 ViewData 和 ViewBag 。这个解决方案的问题在于存在一些安全问题,而且除了警报之外我还无法在客户端运行我的javascript,这对用户来说并不是很有吸引力。
我做的最后一次尝试是使用Ajax请求,以便不会刷新页面,然后我只能在服务器响应后向用户发送通知。这个解决方案的问题是我似乎无法将表单数据提供给后端,它总是填充空值。需要注意的是,我尝试在ContactViewModel之前添加 [FromBody] 属性,因为我在其他帖子中看到它是因为它没有正确绑定但是它对我不起作用。 这是我到目前为止的代码:
一个。对于控制器:
[HttpPost]
[AjaxOnly]
public async Task<IActionResult>SendContactRequest(ContactViewModel model)
{
if (ModelState.IsValid)
{
string recipientEmailAddresses = anyEmail@anyExtension.com;
string subject = "Website customer request from " + model.firstName + " " + model.lastName;
string message = "";
if (model.jobTitle != null)
{
message += "Job title: " + model.jobTitle;
}
message += "Request or comment: " + model.requestMsg;
// Only actually send the message if we are in production/staging or other, anything else than development
if (!_env.IsDevelopment())
{
await _emailSender.SendEmailAsync(model.contactEmail, $"{model.firstName} {model.lastName}", recipientEmailAddresses, subject, message); //using interpolated string here
}
// Sending confirmation via response.writeAsync
await Response.WriteAsync("success");
}
else
{
await Response.WriteAsync("the message could not be sent as model is not valid");
}
// this method redirects to the good section on page, but cannot pass the model along with it...
return Redirect("Index#contact");
}
湾对于客户端:
<form id="contactForm" asp-controller="Home" asp-action="SendContactRequest">
<div class="form-group">
@*<label asp-for="firstName">First Name</label>*@
<input asp-for="firstName" class="form-control" placeholder="First name" />
<span asp-validation-for="firstName" class="text-warning"></span>
</div>
<div class="form-group">
@*<label asp-for="lastName">Last Name</label>*@
<input asp-for="lastName" class="form-control" placeholder="Last name" />
<span asp-validation-for="lastName" class="text-warning"></span>
</div>
<div class="form-group">
@*<label asp-for="contactEmail">Contact Email</label>*@
<input asp-for="contactEmail" class="form-control" placeholder="Full email address" />
<span asp-validation-for="contactEmail" class="text-warning"></span>
<small id="email" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
@*<label asp-for="jobTitle">Job title</label>*@
<input asp-for="jobTitle" class="form-control" placeholder="Job title (optional)" />
<span asp-validation-for="jobTitle" class="text-warning"></span>
</div>
<div class="form-group">
@*<label asp-for="jobTitle">Job title</label>*@
<textarea asp-for="requestMsg" class="form-control" placeholder="Request or comment" rows="8"></textarea>
<span asp-validation-for="requestMsg" class="text-warning"></span>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
℃。最后为脚本部分(Ajax调用):
// Attach a submit handler to the form
$("#contactForm").submit(function (event) {
// Stop form from submitting normally
event.preventDefault();
var formdata = new FormData(document.querySelector('#contactForm')[0]);
// Send the data using ajax
$.ajax({
type: "POST",
url: $form.attr("action"),
data: formdata,
processData: false,
contentType: false,
success: function (response) {
if (response.includes("success")) {
alert(response);
document.getElementById("contactRequestForm").reset();
}
},
error: function () {
alert("Mail not sent, please try again later \n If this error persists, please contact us directly via email @ webmaster@set-ets.com");
}
});
});
答案 0 :(得分:3)
方法4是我推荐的(Ajax)。您的代码中存在发布表单数据的小错误,这就是为什么它不会绑定到您的模型。
// Attach a submit handler to the form
$("#contactForm").submit(function (event) {
// Stop form from submitting normally
event.preventDefault();
// this won't work - take out the indexer
// var formdata = new FormData(document.querySelector('#contactForm')[0]);
// this should work
var formdata = new FormData(document.querySelector('#contactForm'));
// Send the data using ajax
$.ajax({
type: "POST",
url: $form.attr("action"),
data: formdata,
processData: false,
contentType: false,
success: function (response) {
if (response.includes("success")) {
alert(response);
document.getElementById("contactRequestForm").reset();
}
},
error: function () {
alert("Mail not sent, please try again later \n If this error persists, please contact us directly via email @ webmaster@set-ets.com");
}
});
});
但是,您的控制器代码不会按照您的意愿执行。您可能真的希望它返回某种类型的json
类型响应以及任何模型错误等。但是,此代码应该让您达到它正确绑定到模型的程度,然后您就可以摆弄你的控制器方法以返回更合理的东西(不是redirect
)