same httppost function in MVC Controller and MVC ControllerBase, but error find in ControllerBase

Viewed 51

I create the web MVC Core project and have two controller, where main controller is controller and sessiondatacontroller is controllerbase I place the same function as below

[HttpPost]
        public async Task<SessionInfo> GetSessionInfo(string SessionID)
        {
            Console.WriteLine($"Main.GetSessionInfo({SessionID})");
            var getSession = await SessionService.GetSessionInfoAsync(int.Parse(SessionID));
            if (getSession == null) return null;
            return new()
            {
                returnstartdate = getSession.dtStartTime.HasValue ? getSession.dtStartTime.Value.ToString("dd/MM/yy HH:mm:ss") : string.Empty,
                returnenddate = getSession.dtEndTime.HasValue ? getSession.dtEndTime.Value.ToString("dd/MM/yy HH:mm:ss") : string.Empty
            };

        }

For view, in Javascript I call the function as below

function cbSessionChange() {
       
        var url = '@Url.Action("GetSessionInfo", "SessionData")'; 

        var selectvalue = $("#cbSessionList").val(); // Confirm have value
        console.log(`cbSessionList.val : ` + selectvalue.toString())

        $.post(url, { SessionID :selectvalue.toString()},
            function (data) {

                $('#txtDateFr').val(data.returnstartdate);
                $('#txtDateTo').val(data.returnenddate);

            }
        ,'json')
    };

If I call GetSessionInfo(SessionID) in Controller is work, however, I get null parameter value when call GetSessionInfo(SessionID) in ControllerBase. However, I try to use postman to test this two function are both working.

Can I know any wrong inside?

Thank you

1 Answers

$.post method default content type is application/x-www-url-formencoded.

If your ControllerBase declares with [ApiController] attribute, it causes model binding system binds the data from body (content type is application/json)by default.

To achieve your requirement, specific [FromForm] attribute in your ControllerBase:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    [HttpPost]
    public async Task<SessionInfo> GetSessionInfo([FromForm]string SessionID)
    {
         //...
    }
}

Or just remove [ApiController]:

[Route("api/[controller]")]
//[ApiController]
public class ValuesController : ControllerBase
{
    [HttpPost]
    public async Task<SessionInfo> GetSessionInfo(string SessionID)
    {
         //...
    }
}

Update:

If you want to post application/json data by ajax, change like below:

<script>
function cbSessionChange() {

    var url = '@Url.Action("GetSessionInfo", "SessionData")';
    var selectvalue = 1; // Confirm have value
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: url,
        data: JSON.stringify(selectvalue.toString()),   //add this..
        dataType: "json",
        success: function (result, status, xhr) {
            $('#txtDateFr').val(result.returnstartdate);
            $('#txtDateTo').val(result.returnenddate);
        },
        error: function (xhr, status, error) {
            alert("Result: " + status + " " + error + " " + xhr.status + " " + xhr.statusText)
        }
    });
}

Controller:

public class SessionDataController : Controller
{
    [HttpPost]
    public async Task<SessionInfo>  GetSessionInfo([FromBody] string SessionID)
    {
         //...
    }
}
Related