【问题标题】:MVC AJAX POST design concernMVC AJAX POST 设计关注点
【发布时间】:2015-05-26 04:39:24
【问题描述】:

问题背景:

我的 MVC 应用中有一个页面允许用户提交问题,如下所示:

按下“发送”按钮后,将显示带有 Spinner 的模态弹出窗口以显示消息正在发送,然后一旦成功发送,模态内容将被更改以通过适当的消息反映这一点。

潜在的设计问题:

目前我正在使用 AJAX 将文本框值发布到名为 Contact 的控制器,该控制器有一个名为 SendMail 的方法

AJAX POST 功能:

<script>
$("#SendMessage").click(function (e) {

    $("#SendingModal").modal('show');

    $.ajax({
        url: '@Url.Action("SendMail")',
        type: 'POST',
        data: {
            "name": $('#name').val(),
            "email": $('#email').val(),
            "subject": $('#subject').val(),
            "message": $('#message').val()
        },
        success: function () {
            $('#contactForm').html('<div class="row">' +
                '<div class="col-lg-12 col-md-12 col-sm-12">' +
                '<div class="jumbotron jumbotronPadding">' +
                '<h2>Message sent</h2>' +
                '<p><h3>Thank your for your enquiry, we will reply as soon as possible.</h3></p>' +
                '</div>' +
                '</div>' +
                '</div>');

            $('#SendingModal').modal('hide');
        }
    });
});

SendMail 方法通过 AJAX POST 请求获取联系人页面发送的参数:

     public void SendMail(string name, string email, string subject, string message)
    {
        var mailMessage = new EmailContactHandler();

        mailMessage.SendMail(name, email, subject, message);
    }

我应该使用Html Form 而不是当前的 AJAX 调用吗?目前,我将每个单独的文本框值发布到 SendMail 方法上的相关参数值,即名称、电子邮件、主题、消息。表格将允许我通过ViewModel 发送这些。我目前的实施还好吗?如果不是什么是更好的方法(最好使用某种模型)

更新:

阅读 Mackans 的回答后,我重构了代码以映射到一个名为 Contact 的模型,以在 AJAX 请求中设置数据属性。

AJAX 请求:

<script>
$("#SendMessage").click(function (e) {

    $("#dialog-example").modal('show');

    $.ajax({
        url: '@Url.Action("SendMail")',
        type: 'POST',
        data: {
            name: $('#name').val(),
            email: $('#email').val(),
            subject: $('#subject').val(),
            message: $('#message').val()
        },
        success: function (message) {
            if (message.messageStatus === "success") {
                $('#contactForm').html('<div class="row">' +
                    '<div class="col-lg-12 col-md-12 col-sm-12">' +
                    '<div class="jumbotron jumbotronPadding">' +
                    '<h2>Message sent</h2>' +
                    '<p><h3>Thank your for your enquiry, we will reply as soon as possible.</h3></p>' +
                    '</div>' +
                    '</div>' +
                    '</div>');
            }

            $('#dialog-example').modal('hide');
        }
    });
});

联系型号:

public class Contact
{
    public string Name { set; get; }
    public string Email { set; get; }
    public string Subject { set; get; }
    public string Message { set; get; }
}

控制器上的 SendMail 方法现在采用名为 Contact 的模型实例。

 public ActionResult SendMail(Contact emailMessage)
        {
            var mailMessage = new EmailContactHandler();

            mailMessage.SendMail(emailMessage);

            return Json(new { messageStatus = "success"});
        }

【问题讨论】:

  • 您当前的实现没问题。没有什么能阻止您使用具有相同字段名称的 inputmodel。在某些情况下,您可以编写自己的模型绑定器。
  • 您能否解释一下 - “..A Form 将允许我通过 ViewModel 发送这些”?您的意思是动作输入模型?另外,SendMail 是断章取义的,它不是操作方法。
  • @AntonPutau 谢谢cmets。我正在考虑使用一个 Html.BeginForm,然后我可以绑定到一个 ViewModel(它具有发送到 SendMail 方法的名称、电子邮件、主题和消息的公共属性。

标签: jquery ajax asp.net-mvc


【解决方案1】:

您的设计有效,但正如您自己所说,您错过了 MVC 中的 M。幸运的是,您无需在 Ajax 和模型之间进行选择。

唯一的问题是可用的选项太多了,写一个详细的演练不适合这种格式。简而言之:

  • 您可以将模型和Html.BeginForm() 或类似名称添加到您当前的解决方案并在您当前的代码中处理它。模型通常在控制器中绑定没有问题..

     e.preventDefault(); //to prevent normal submit
     $.ajax({
        url: '@Url.Action("SendMail")',
        type: 'POST',
        data: $('#myform').serialize(),
        ...
    

    控制器:

    [HttpPost]
    public void SendMail(MyModel model)
    
  • 您也可以,或者改为使用 Microsoft 的 Ajax 扩展:

    @using (Ajax.BeginForm("MyAction", "MyController", new AjaxOptions
       {
            HttpMethod = "POST",
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = "myTargetElementId"
       }))
    

    有很多good options available。但是没有什么不能只使用 jQuery 来完成。这只是一个偏好问题,它们可以混合搭配。

有关这些方法和其他方法的更多详细信息,请在 SO 或 Google 上搜索。周围有很多很好的指南。

另外,因为您询问的是潜在问题。我会从SendMail 方法返回某种形式的成功或失败。 Ajax 成功只能告诉你方法是否被成功调用,而不是结果。

【讨论】:

  • 非常感谢您的回答。现在我已经实现了一个模型,我的 AJAX 请求从“数据”属性映射到。您能否查看我的问题中“更新”下的部分,看看这是否是更好的方法。
  • 看起来不错@user1352057。您不需要在 SendMail 中启动新的联系人,因为您已经获得了一个作为参数。您也可以将整个表单(序列化)映射到 ajax 数据选项,但它可以正常工作,因为它只有 4 个元素:)
  • @再次感谢 Mackan。作为最后一个问题,我有另一个与此非常相似但发布 25 个元素的观点,我可以对这么多元素使用相同的方法吗?
  • @user1352057 是的,但是您真的应该考虑使用我在回答中发布的$('form').serialize(),以免您编写和保持 25 个元素是最新的。您只需要添加表单,并阻止它提交。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
  • 2020-11-25
相关资源
最近更新 更多