user1352057
user1352057

Reputation: 3182

MVC AJAX POST design concern

Question background:

I have a page in my MVC app that allows a user to submit a question as shown:

enter image description here

Once the Send button has been pressed a Modal Pop-up displays with a Spinner to show the message is being sent then once successfully sent the modals contents will be changed to reflect this with a appropriate message.

Potential Design Concerns:

Currently I am using AJAX to post the textbox values to a controller called Contact which has a method called SendMail

AJAX POST function:

<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');
        }
    });
});

The SendMail method that takes the parameters sent from the Contact page through the AJAX POST request:

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

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

Should I be using a Html Form instead of the current AJAX call? Currently I'm posting each individual textbox value to its relevant parameter value on the SendMail method i.e name, email, subject, message. A Form would allow me to send these by a ViewModel. Is my current implementation ok? If not what would be a better method (ideally using some sort of model)

Update:

After reading Mackans answer I have refactored the code to map to a model called Contact to the set data properties in the AJAX request.

AJAX request:

<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');
        }
    });
});

Contact model:

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

The SendMail method on the controller that now takes an model instance called Contact.

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

            mailMessage.SendMail(emailMessage);

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

Upvotes: 1

Views: 120

Answers (1)

Mackan
Mackan

Reputation: 6271

Your design works, but as you say yourself you're missing out on the M in MVC. Lucky for you there is no need to choose between Ajax and models.

The only problem is that there are so many options available, that writing a detailed walkthrough on all would not fit this format. To put it very simply though:

  • You can add a model, and Html.BeginForm() or similar, to your current solution and handle it in your current code. The model will usually have no problem binding in the controller..

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

    Controller:

    [HttpPost]
    public void SendMail(MyModel model)
    
  • You can also, or instead, use the Microsofts Ajax extensions:

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

    There are many good options available. But nothing that can't be done using just jQuery. It's just a matter of preference, and they can be mixed and matched.

For more details on these methods, and others, search on SO or Google. There are plenty of good guides around.

Also, since you were asking about potential concerns. I would return some form of success or failure from the SendMail method. The Ajax success can only tell you if the method got called successfully, not what the outcome was.

Upvotes: 1

Related Questions