V.Prasad
V.Prasad

Reputation: 151

Jquery Ajax call passed parameter always null in Asp.net MVC Core

I am migrating my MVC application to Asp.Net core (3.1 version) application. I have one layout page which is used for menu navigation. When user click on any menu then i need to pass some value from Layout to the controller for some business purpose. To do that i used one ajax call here.

Below ajax call code is working fine in MVC, But in Asp.Net core the passed parameter value is null in controller.

Working code of MVC:

function SetCurrentPageNameSession(currentPageName, isBookMarkPage) {

        if(isBookMarkPage==undefined)
            isBookMarkPage = false;
        var url = baseUrl+"Manage/HighlightCurrentMenu/"
            $.ajax({
            type: "POST",
            data: "{'CurrentPage':'" + currentPageName + "', 'IsBookMark':'" + isBookMarkPage + "'}",
                url: url,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                async:false,
                success: function (data) {
                var res = data.d;
            },
                error: function (xhr, ajaxOptions, thrownError) {

            }
        });
    }

and below is the controller action method where i get these passed value:

[HttpPost]
        public IActionResult HighlightCurrentMenu(string CurrentPage, bool IsBookMark)
        {
           return Json(true);
        }

When the same code not works in Asp.Net core then i googled it and found like need to modify the ajax call code.

I modified data section in below:

function SetCurrentPageNameSession(CurrentPage, IsBookMark) {

        var url = baseUrl+"Manage/HighlightCurrentMenu/"
            $.ajax({
            type: "POST",
            data: JSON.stringify({ CurrentPage: CurrentPage, IsBookMark: IsBookMark }),
                url: url,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                async:false,
                success: function (data) {
                var res = data.d;
            },
                error: function (xhr, ajaxOptions, thrownError) {

            }
        });
    }

And used FromBody in controller action method:

[HttpPost]
        public IActionResult HighlightCurrentMenu([FromBody] string CurrentPage, [FromBody] bool IsBookMark)
        {
          return Json(true);  
        }

I get the value null in "CurrentPage" Parameter.

I tried one more scenario by myself in below:

data: JSON.stringify("{'CurrentPage':'" + CurrentPage + "', 'IsBookMark':'" + IsBookMark + "'}"),

In this case i get complete Json format value in "CurrentPage" parameter inside action method

Below is the screen shot for the same.

Screenshot attached

Please suggest.

Upvotes: 1

Views: 8304

Answers (4)

S.A.Parkhid
S.A.Parkhid

Reputation: 2870

Try to remove this line from your ajax call:

contentType: "application/json; charset=utf-8"

Upvotes: 1

Farid Huseynov
Farid Huseynov

Reputation: 159

You probably don't need to specify that you are sending dataType of json. I have tried the below and it worked

    function SetCurrentPageNameSession(currentPageName, isBookMarkPage) {
        if(isBookMarkPage==undefined)
            isBookMarkPage = false;
        var url = baseUrl+"Manage/HighlightCurrentMenu/";
        $.ajax({
            type: "POST",
            data: { CurrentPage: currentPageName, IsBookMark: isBookMarkPage },
            url: url,
            success: function (data) {
                var res = data.d;
            },
            error: function (xhr, ajaxOptions, thrownError) {

            }
        });
    }

Upvotes: 2

VivekDev
VivekDev

Reputation: 25389

After a good 3 hours of struggle, here is what worked for me.

using Microsoft.AspNetCore.Mvc;

namespace NR1003009DynamicNRules.Controllers {
    [Route("api/[controller]")]
    [ApiController]
    public class DynamicNRulesController : Controller {
        [HttpPost("ProcessTextRule")]
        public JsonResult ProcessTextRule([FromBody] Customer customer) {
            var cusName = customer.ContactName;
            return Json("");
        }
    }
    
    public class Customer {
        public string ContactName { get; set; }
    }
}

// Javascript Client
function PostTheRuleToServer() {

    var data = { ContactName: "The customer name" };
    var getWorkflowDetailsUrl = "api/DynamicNRules/ProcessTextRule"

    $.ajax({
        type: "POST",
        url: getWorkflowDetailsUrl,
        data: JSON.stringify(data),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (msg) {
            alert(msg);
        },
        error: function (req, status, error) {
            alert(error);
        }
    });
}

I tried removing attribute routing on the controller and action method and the following also worked.

using Microsoft.AspNetCore.Mvc;

namespace NR1003009DynamicNRules.Controllers {
    public class DynamicNRulesController : Controller {
        public JsonResult ProcessTextRule([FromBody] Customer customer) {
            var cusName = customer.ContactName;
            return Json("");
        }
    }
    
    public class Customer {
        public string ContactName { get; set; }
    }
}

// Javascript Client. Note the changed url below. 
function PostTheRuleToServer() {
    var data = { ContactName: "The customer name" };
    var getWorkflowDetailsUrl = "DynamicNRules/ProcessTextRule"
    $.ajax({
        type: "POST",
        url: getWorkflowDetailsUrl,
        data: JSON.stringify(data),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (msg) {
            alert(msg.foo);
        },
        error: function (req, status, error) {
            alert(error);
        }
    });
}

Upvotes: 1

Fei Han
Fei Han

Reputation: 27793

in Asp.Net core the passed parameter value is null in controller

From this doc, you could find:

Don't apply [FromBody] to more than one parameter per action method. Once the request stream is read by an input formatter, it's no longer available to be read again for binding other [FromBody] parameters.

To achieve your requirement of passing multiple data from JS client side to controller action method, you can try following code snippet.

[HttpPost]
public IActionResult HighlightCurrentMenu([FromBody]PageInfo pageInfo)
{
    var currentPage = pageInfo?.CurrentPage;
    var isBookMark = pageInfo?.IsBookMark;

    //...
    //code logic here

    return Json(true);
}

PageInfo class

public class PageInfo
{
    public string CurrentPage { get; set; }
    public bool IsBookMark { get; set; }
}

On JS client side

data: JSON.stringify({ "CurrentPage": CurrentPage, "IsBookMark": IsBookMark }),

Test Result

enter image description here

Upvotes: 3

Related Questions