iaswmn
iaswmn

Reputation: 39

asp.net-mvc ajax json post to controller action method

I know that same questions have answers, but they don't work in my project. I have controller were i send message to employee. id i take with ajax. email i take from db. but getEmployeeEmail() returns me my email( it's right) Controller name: EmployersActivity

Code don't work when i send post. My ajax post code:

$(document).ready(function () {
        $(".buttonSendEmail").click(function () {
            var orderText = $(".orderData").text();
            alert(orderText);
            $.ajax({
                type: "POST",
                contentType: 'application/json; charset=utf-8',
                url: "@(Url.Action("Create", "EmployersActivity"))",
                data: { id: 1 },
                dataType: "json",
                traditional: true,
                error: function (message) {
                    alert("error on start")
                    $(".contentReqGood").show();
                    redirect();
                },
                success: function (result) {
                    if (result.status === 1) {
                        alert("error")
                    } else {
                        $(".contentReqGood").show();
                        redirect();}})})});

asp.net mvc code:

    [HttpGet]
    [Authorize]
    public ActionResult Create()
    {
        return View();
    }

    [HttpPost]
    [Authorize]
    [ValidateAntiForgeryToken]
    public ActionResult Create(int? id)
    {
        if (id == null)
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

        var email = db.employees.Find(id);
        if (email == null)
            return HttpNotFound();
        if (email != null)
        {


            if (db.SaveChanges() == 1)
            {
                string mailTemplate;
                string title = "asdasd";
                string preview = "asdasdasd";
                var sr = new StreamReader(Server.MapPath("~/App_Data/Templates/" + "InfoEmail.txt"));

                mailTemplate = sr.ReadToEnd();

                string messageBody = string.Format(mailTemplate, title, preview);

                new MailSender
                {
                    Sender = "[email protected]",
                    Recipient = "[email protected]",
                    RecipientsBcc = getEmployeeEmail(),
                    Subject = title,
                    Body = messageBody
                }.Send();}}
        return View();}

Upvotes: 0

Views: 722

Answers (1)

Tetsuya Yamamoto
Tetsuya Yamamoto

Reputation: 24957

You have several issues regarding current example:

1) [Authorize] attribute is unnecessary on POST method because using it in GET action method should be enough to prevent unauthorized users.

2) Since you're sending AJAX request to a POST method which includes [ValidateAntiForgeryToken] attribute, it is necessary to send the CSRF prevention token into AJAX request.

3) Remove dataType: "json", contentType: 'application/json; charset=utf-8' and traditional: true since you're sending single integer data and not using an array or JSON-formatted string.

4) AJAX callbacks are intended to stay in same page, hence return View() should be replaced with return PartialView().

Based from 4 issues above, if it's necessary to use AJAX, you should set the request and controller action like following example below:

AJAX Request

$(document).ready(function () {
    $(".buttonSendEmail").click(function () {
        var orderText = $(".orderData").text();
        alert(orderText);

        var form = $('form');
        var token = $('input[name="__RequestVerificationToken"]', form).val();

        $.ajax({
            type: "POST",
            url: "@Url.Action("Create", "EmployersActivity")",
            data: { id: 1, __RequestVerificationToken: token },
            error: function (message) {
                alert("error on start");
                // other stuff
            },
            success: function (result) {
                $(".contentReqGood").show();
                // other stuff
            }
        });
    });
});

Controller Action

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(int? id)
{
    if (id == null)
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

    var email = db.employees.Find(id);
    if (email == null)
        return HttpNotFound();
    if (email != null)
    {
        // do something
    }
    return PartialView("_PartialViewName");
}

Other than that, if you want to pass entire viewmodel content to POST action method or use redirection with RedirectToAction() after submit, then you should use normal form submit (with Html.BeginForm() helper) instead.

Upvotes: 1

Related Questions