【问题标题】:asp.net core user notification after form post表单发布后的asp.net核心用户通知
【发布时间】:2016-09-27 20:59:27
【问题描述】:

好的,这是我在这里的第一个问题,所以我会尽量说清楚,不要重复其他人之前问过的问题。我确实尝试在发布之前在论坛上进行搜索,但我发现没有任何东西可以帮助我解决我的问题。如果我错过了一个合适的答案,请轻轻地关闭这个问题作为重复。

所以我的目标是在部分视图中发布表单后向用户发送通知,告诉他它是否有效或后端是否存在问题。我也不希望仅仅为了显示通知而重新加载整个视图。

我的问题是,在不刷新整个视图的情况下,将通知从后端发送到 UI 的最佳方式是什么。

这是我迄今为止尝试过的方法以及为什么它不起作用:

  1. 第一次尝试是将数据添加到 ViewData 字典并将其传递给视图。它可以工作,但会再次加载整个页面,这是不受欢迎的。

  2. 正如我通过搜索看到的,在返回视图之前重定向到 GET 请求是一种很好的做法,我创建了一个重定向到成功方法,然后将显示 ViewData 字典,但我发现它不起作用,因为重定向不允许我通过 viewdata 传递任何内容。

  3. 之后我发现我可以使用 TempData,因为它通过重定向而不是 ViewDataViewBag。这个解决方案的问题是存在一些安全问题,而且我无法在客户端运行我的javascript,除了一个警报,这对用户来说并不是很有吸引力。

  4. 我最后一次尝试是使用 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");
    }

b.对于客户端:

<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>

c。最后是脚本部分(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");
            }
        });
    });

【问题讨论】:

    标签: jquery asp.net ajax asp.net-mvc asp.net-core


    【解决方案1】:

    方法 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

    【讨论】:

    • 或者使用 jquery 获取表单数据:var formdata = new FormData($('#contactForm')[0]);——也许这就是你的初衷。
    • 感谢您的意见。对于控制器,它实际上做了我想要的,因为模型错误的验证是在发布请求之前在客户端完成的。至于索引,我不知道为什么,但如果我按照建议删除它,我的调试控制台(Chrome 开发工具)中会出现以下错误:“Argument not optional”
    • 错误发生在哪里?当我在本地测试时,我确实必须将 $form.attr 更改为 $("#contactForm").attr 但我不确定您是否使用了我没有的插件,所以我在帖子中保持不变。也许就是这样?或者,在我的第一条评论中尝试 jquery 语法。
    • jquery 表单似乎按预期工作(您所做的第二条评论),我以为我已经尝试过了,但也许我第一次尝试时有错字,这就是我去尝试“香草”的原因“ javascript 的方式并将索引放在那里我猜。总的来说,您认为这是向用户发送通知的最佳方式还是有更好的选择?
    • 考虑到您想要的用户交互(无需重新加载等),ajax 对我来说最有意义。
    猜你喜欢
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 2017-04-03
    • 1970-01-01
    • 2019-06-05
    相关资源
    最近更新 更多