0

I wanted to take advantage of async in JavaScript, but the function will simply not POST the data to the API (it's ALWAYS null, be it a simple variable or an object). I've scoured around the Internet for hours and tried everything I can think of, verified that the variable is set on the JavaScript side and the API is always called, however, the value is null - it's POSTing but, never actually sends the data.

Here's the jQuery/JavaScript function.

async function RetrieveProfile(userId) {
    let result;
    try {
        result = await $.ajax({
            url: '../../api/GetProfile',
            dataType: 'json',
            method: 'post',
           data: { UserId: userId }
        });
        return result;
    } catch (e) {
        console.error(e);
    }
}

I've tried setting data: to just userId, tried stringify, tried removing dataType: 'json', tried with and without contentType, no joy. I know the API works, because I can call it from Postman and get the results back (though, that's synchronous).

As per every post on Stack Overflow, this should work (I've had async JavaScript work fine for years before, but they've always posted to ASMX instead of WebApi, so there must be some other change that needs to be made for this to POST correctly).

(NB: this is not DotNet core. There is no middleware).

[Route("api/GetProfile")]
[HttpPost]
public async Task<IHttpActionResult> GetProfile([FromBody] string UserId)
{
    var retval = new Profile();
    if (UserId != null)
    {
        if (await dbv.IsValidUserIdAsync(UserId))
        {
            retval = await profile_Data.GetProfileAsync(UserId);
        }
    }
    return Ok(retval);
}

I can step through the JavaScript and look at the userId and it's set to a value (I even set a dummy variable inside the try...catch to verify it still has a value. On the API side, UserId is null. I've tried setting it to an object - still null. If I remove [FromBody], I get a 404 error (and the endpoint is not hit). I believe that, either the API doesn't recognize any data that's not from the HTML DOM - ignoring the parameter OR there's a bug in jQuery 3.1.1 - which I can't upgrade to 4.x or 5.x without breaking the website in other places.

Any ideas? Real working examples? Working solutions I can download? I have read the manual, but can't find a specific case example (jQuery 3.x + async + WebAPI 2.0 + non-DotNetCore).

halfer
  • 19,824
  • 17
  • 99
  • 186
MC9000
  • 2,076
  • 7
  • 45
  • 80
  • this is about c# but maybe could help https://stackoverflow.com/questions/40853188/frombody-string-parameter-is-giving-null – GrafiCode Oct 01 '22 at 18:42

1 Answers1

0

okay - I figured it out. I was correct in that FromBody only allows values (like it says) from the HTML body. So the data is ignored by WebApi (they need a [FromParam] or something like that (an oversight on MS's part).

So I switched it from a POST to a GET on both the client and the webapi.

Client (JQuery/Javascript) side:

async function RetrieveProfile(userId) {
    let result;
    try {
        result = await $.ajax({
            url: '../../api/GetProfile',
            method: 'get',
           data: { UserId: userId }
        });
        return result;
    } catch (e) {
        console.error(e);
    }
}

On the webAPI side, I changed the code as so:

    [Route("api/GetProfile")]
    [HttpGet]
    public async Task<IHttpActionResult> GetProfile([FromUri] string UserId)
    {
        var retval = new Profile();
        if (UserId != null)
        {
            if (await dbv.IsValidUserIdAsync(UserId))
            {
                retval = await profile_Data.GetProfileAsync(UserId);
            }
        }
        return Ok(retval);
    }

Works perfectly now, but this is only good for GET, so solving the POST problem for the Update/Insert objects will be for the next question (since FromBody completely ignores posted data: if async javascript is used - the nightmare continues)

MC9000
  • 2,076
  • 7
  • 45
  • 80
  • Figured out that you must remove the FromBody attribute if passing an object via POSTing or PUTing. (I solved the other half of my dilemma - I wish MS would put this in their docs) – MC9000 Oct 01 '22 at 19:10